X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/c8724d0d7b016371309f189636b0992ea413bd96..4ed3a1ba4db2e01d717149e350e867d23cdd1b7b:/lib/gdi/font.cpp diff --git a/lib/gdi/font.cpp b/lib/gdi/font.cpp index f7699b9c..a5db43a9 100644 --- a/lib/gdi/font.cpp +++ b/lib/gdi/font.cpp @@ -6,6 +6,11 @@ #include #include #include +#include + +#ifndef BYTE_ORDER +#error "no BYTE_ORDER defined!" +#endif // use this for init Freetype... #include @@ -41,8 +46,6 @@ static pthread_mutex_t ftlock=PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP; static FTC_Font cache_current_font=0; #endif -#define RBG565 - struct fntColorCacheKey { gRGB start, end; @@ -343,6 +346,8 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly i->x-=offset.x(); i->y-=offset.y(); i->bbox.moveBy(-offset.x(), -offset.y()); + --lineChars.back(); + ++charCount; } while (i-- != glyphs.rbegin()); // rearrange them into the next line cursor+=ePoint(linelength, 0); // put the cursor after that line } else @@ -380,6 +385,7 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly ng.glyph_index = glyphIndex; ng.flags = flags; glyphs.push_back(ng); + ++charCount; /* when we have a SHY, don't xadvance. It will either be the last in the line (when used for breaking), or not displayed. */ if (!(flags & GS_SOFTHYPHEN)) @@ -427,7 +433,13 @@ void eTextPara::newLine(int flags) cursor.setX(left); previous=0; int linegap=current_face->size->metrics.height-(current_face->size->metrics.ascender+current_face->size->metrics.descender); + + lineOffsets.push_back(cursor.y()); + lineChars.push_back(charCount); + charCount=0; + cursor+=ePoint(0, (current_face->size->metrics.ascender+current_face->size->metrics.descender+linegap)>>6); + if (maximum.height()visual reordering -#ifdef HAVE_FRIBIDI + int size=uc_shape.size(); +#ifdef HAVE_FRIBIDI FriBidiCharType dir=FRIBIDI_TYPE_ON; - { - int size=uc_shape.size(); - uc_visual.resize(size); - // gaaanz lahm, aber anders geht das leider nicht, sorry. - FriBidiChar array[size], target[size]; - std::copy(uc_shape.begin(), uc_shape.end(), array); - fribidi_log2vis(array, size, &dir, target, 0, 0, 0); - uc_visual.assign(target, target+size); - } + uc_visual.resize(size); + // gaaanz lahm, aber anders geht das leider nicht, sorry. + FriBidiChar array[size], target[size]; + std::copy(uc_shape.begin(), uc_shape.end(), array); + fribidi_log2vis(array, size, &dir, target, 0, 0, 0); + uc_visual.assign(target, target+size); #else uc_visual=uc_shape; #endif - glyphs.reserve(uc_visual.size()); + glyphs.reserve(size); int nextflags = 0; @@ -706,8 +716,19 @@ nprint: isprintable=0; calc_bbox(); #ifdef HAVE_FRIBIDI if (dir & FRIBIDI_MASK_RTL) + { realign(dirRight); + doTopBottomReordering=true; + } #endif + + if (charCount) + { + lineOffsets.push_back(cursor.y()); + lineChars.push_back(charCount); + charCount=0; + } + return 0; } @@ -772,8 +793,7 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons for (int i=0; i<16; ++i) { #define BLEND(y, x, a) (y + (((x-y) * a)>>8)) - - unsigned char dr = background.r, dg = background.g, db = background.b; + unsigned char da = background.a, dr = background.r, dg = background.g, db = background.b; int sa = i * 16; if (sa < 256) { @@ -782,11 +802,12 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons db = BLEND(background.b, foreground.b, sa) & 0xFF; } #undef BLEND -#ifdef RBG565 - lookup16_normal[i] = ((dr >> 3) << 11) | ((db >> 2) << 5) | (dg >> 3); +#if BYTE_ORDER == LITTLE_ENDIAN + lookup16_normal[i] = bswap_16(((db >> 3) << 11) | ((dg >> 2) << 5) | (dr >> 3)); #else - lookup16_normal[i] = ((dr >> 3) << 11) | ((dg >> 2) << 5) | (db >> 3); + lookup16_normal[i] = ((db >> 3) << 11) | ((dg >> 2) << 5) | (dr >> 3); #endif + da ^= 0xFF; } for (int i=0; i<16; ++i) lookup16_invert[i]=lookup16_normal[i^0xF]; @@ -822,11 +843,21 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons gRegion clip = dc.getClip() & area; int buffer_stride=surface->stride; - + for (unsigned int c = 0; c < clip.rects.size(); ++c) { - for (glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i) + std::list::reverse_iterator line_offs_it(lineOffsets.rbegin()); + std::list::iterator line_chars_it(lineChars.begin()); + int line_offs=0; + int line_chars=0; + for (glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i, --line_chars) { + while(!line_chars) + { + line_offs = *(line_offs_it++); + line_chars = *(line_chars_it++); + } + if (i->flags & GS_SOFTHYPHEN) continue; @@ -841,13 +872,13 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons lookup16 = lookup16_invert; lookup32 = lookup32_invert; } - + static FTC_SBit glyph_bitmap; if (fontRenderClass::instance->getGlyphBitmap(&i->font->font, i->glyph_index, &glyph_bitmap)) continue; int rx=i->x+glyph_bitmap->left + offset.x(); - int ry=i->y-glyph_bitmap->top + offset.y(); - + int ry=(doTopBottomReordering ? line_offs : i->y) - glyph_bitmap->top + offset.y(); + __u8 *d=(__u8*)(surface->data)+buffer_stride*ry+rx*surface->bypp; __u8 *s=glyph_bitmap->buffer; register int sx=glyph_bitmap->width;