X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fgdi%2Ffont.cpp;h=3a32e2a11e9ad77f546e2592396689407c38f0e5;hp=2fd9fb691331efbeb316e8b9f2e33777e9368620;hb=HEAD;hpb=71f4f597f7e929d2d3bbc726ed84b97b055113f8 diff --git a/lib/gdi/font.cpp b/lib/gdi/font.cpp index 2fd9fb6..3a32e2a 100644 --- a/lib/gdi/font.cpp +++ b/lib/gdi/font.cpp @@ -6,16 +6,19 @@ #include #include #include +#include + +#ifndef BYTE_ORDER +#error "no BYTE_ORDER defined!" +#endif // use this for init Freetype... #include #include FT_FREETYPE_H -#ifdef HAVE_FREETYPE2 #define FTC_Image_Cache_New(a,b) FTC_ImageCache_New(a,b) #define FTC_Image_Cache_Lookup(a,b,c,d) FTC_ImageCache_Lookup(a,b,c,d,NULL) #define FTC_SBit_Cache_New(a,b) FTC_SBitCache_New(a,b) #define FTC_SBit_Cache_Lookup(a,b,c,d) FTC_SBitCache_Lookup(a,b,c,d,NULL) -#endif #include #include @@ -24,12 +27,7 @@ #include #include -#define HAVE_FRIBIDI -// until we have it in the cdk - -#ifdef HAVE_FRIBIDI #include -#endif #include @@ -37,10 +35,6 @@ fontRenderClass *fontRenderClass::instance; static pthread_mutex_t ftlock=PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP; -#ifndef HAVE_FREETYPE2 -static FTC_Font cache_current_font=0; -#endif - struct fntColorCacheKey { gRGB start, end; @@ -124,6 +118,32 @@ FT_Error fontRenderClass::getGlyphBitmap(FTC_Image_Desc *font, FT_ULong glyph_in return res; } +FT_Error fontRenderClass::getGlyphImage(FTC_Image_Desc *font, FT_ULong glyph_index, FT_Glyph *glyph, FT_Glyph *borderglyph, int bordersize) +{ + FT_Glyph image; + FT_Error err = FTC_ImageCache_Lookup(imageCache, font, glyph_index, &image, NULL); + if (err) return err; + + if (glyph) + { + err = FT_Glyph_Copy(image, glyph); + if (err) return err; + } + + if (borderglyph && bordersize) + { + err = FT_Glyph_Copy(image, borderglyph); + if (err) return err; + if (bordersize != strokerRadius) + { + strokerRadius = bordersize; + FT_Stroker_Set(stroker, strokerRadius, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); + } + err = FT_Glyph_Stroke(borderglyph, stroker, 1); + } + return err; +} + std::string fontRenderClass::AddFont(const std::string &filename, const std::string &name, int scale) { eDebugNoNewLine("[FONT] adding font %s...", filename.c_str()); @@ -191,7 +211,12 @@ fontRenderClass::fontRenderClass(): fb(fbClass::getInstance()) { eDebug("[FONT] initializing font cache imagecache failed!"); } + if (FT_Stroker_New(library, &stroker)) + { + eDebug("[FONT] initializing font stroker failed!"); + } } + strokerRadius = -1; return; } @@ -205,12 +230,8 @@ float fontRenderClass::getLineHeight(const gFont& font) return 0; singleLock s(ftlock); FT_Face current_face; -#ifdef HAVE_FREETYPE2 if ((FTC_Manager_LookupFace(cacheManager, fnt->scaler.face_id, ¤t_face) < 0) || (FTC_Manager_LookupSize(cacheManager, &fnt->scaler, &fnt->size) < 0)) -#else - if (FTC_Manager_Lookup_Size(cacheManager, &fnt->font.font, ¤t_face, &fnt->size)<0) -#endif { eDebug("FTC_Manager_Lookup_Size failed!"); return 0; @@ -258,7 +279,6 @@ DEFINE_REF(Font); Font::Font(fontRenderClass *render, FTC_FaceID faceid, int isize, int tw): tabwidth(tw) { renderer=render; -#ifdef HAVE_FREETYPE2 font.face_id = faceid; font.width = isize; font.height = isize; @@ -267,12 +287,6 @@ Font::Font(fontRenderClass *render, FTC_FaceID faceid, int isize, int tw): tabwi scaler.width = isize; scaler.height = isize; scaler.pixel = 1; -#else - font.font.face_id=faceid; - font.font.pix_width = isize; - font.font.pix_height = isize; - font.image_type = ftc_image_grays; -#endif height=isize; if (tabwidth==-1) tabwidth=8*isize; @@ -284,21 +298,79 @@ FT_Error Font::getGlyphBitmap(FT_ULong glyph_index, FTC_SBit *sbit) return renderer->getGlyphBitmap(&font, glyph_index, sbit); } +FT_Error Font::getGlyphImage(FT_ULong glyph_index, FT_Glyph *glyph, FT_Glyph *borderglyph, int bordersize) +{ + return renderer->getGlyphImage(&font, glyph_index, glyph, borderglyph, bordersize); +} + Font::~Font() { } DEFINE_REF(eTextPara); -int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt glyphIndex, int flags, int rflags) +int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt glyphIndex, int flags, int rflags, int border, bool activate_newcolor, unsigned long newcolor) { - FTC_SBit glyph; - if (current_font->getGlyphBitmap(glyphIndex, &glyph)) - return 1; + int xadvance, left, top, height; + pGlyph ng; + int xborder = 0; + + if (border) + { + /* TODO: scale border radius with current_font scaling */ + if (current_font->getGlyphImage(glyphIndex, &ng.image, &ng.borderimage, 64 * border)) + return 1; + if (ng.image && ng.image->format != FT_GLYPH_FORMAT_BITMAP) + { + FT_Glyph_To_Bitmap(&ng.image, FT_RENDER_MODE_NORMAL, NULL, 1); + if (ng.image->format != FT_GLYPH_FORMAT_BITMAP) return 1; + } + if (ng.borderimage && ng.borderimage->format != FT_GLYPH_FORMAT_BITMAP) + { + FT_Glyph_To_Bitmap(&ng.borderimage, FT_RENDER_MODE_NORMAL, NULL, 1); + if (ng.borderimage->format != FT_GLYPH_FORMAT_BITMAP) return 1; + } + FT_BitmapGlyph glyph = NULL; + if (ng.borderimage) + { + xadvance = ng.borderimage->advance.x; + if (!previous) + { + /* Move the first character, to make sure the border does not get cut off by the boundingbox (xborder is in pixel units, so just divide the width difference by two) */ + xborder = (((FT_BitmapGlyph)ng.borderimage)->bitmap.width - ((FT_BitmapGlyph)ng.image)->bitmap.width) / 2; + } + glyph = (FT_BitmapGlyph)ng.borderimage; + } + else if (ng.image) + { + xadvance = ng.image->advance.x; + glyph = (FT_BitmapGlyph)ng.image; + } + else + { + return 1; + } + xadvance >>= 16; + + left = glyph->left; + top = glyph->top; + height = glyph->bitmap.rows; + } + else + { + FTC_SBit glyph; + if (current_font->getGlyphBitmap(glyphIndex, &glyph)) + return 1; + + xadvance = glyph->xadvance; + left = glyph->left; + top = glyph->top; + height = glyph->height; + } int nx=cursor.x(); - nx+=glyph->xadvance; + nx+=xadvance; if ( (rflags&RS_WRAP) && @@ -341,6 +413,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 @@ -353,8 +427,7 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly } } - int xadvance=glyph->xadvance, kern=0; - + int kern=0; if (previous && use_kerning) { FT_Vector delta; @@ -362,22 +435,28 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly kern=delta.x>>6; } - pGlyph ng; - ng.bbox.setLeft( (flags&GS_ISFIRST|cursor.x()-1)+glyph->left ); - ng.bbox.setTop( cursor.y() - glyph->top ); - ng.bbox.setWidth( glyph->width ); - ng.bbox.setHeight( glyph->height ); + ng.bbox.setLeft( ((flags&GS_ISFIRST)|(cursor.x()-1))+left ); + ng.bbox.setTop( cursor.y() - top ); + ng.bbox.setHeight( height ); - xadvance += kern; + xadvance += kern + xborder; ng.bbox.setWidth(xadvance); - ng.x = cursor.x()+kern; + ng.x = cursor.x()+kern+xborder; ng.y = cursor.y(); ng.w = xadvance; ng.font = current_font; ng.glyph_index = glyphIndex; ng.flags = flags; + + if (activate_newcolor) + { + ng.flags |= GS_COLORCHANGE; + ng.newcolor = newcolor; + } + 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)) @@ -425,7 +504,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()cacheManager, replacement_font->scaler.face_id, &replacement_face) < 0) || (FTC_Manager_LookupSize(fontRenderClass::instance->cacheManager, &replacement_font->scaler, &replacement_font->size) < 0)) -#else - if (FTC_Manager_Lookup_Size(fontRenderClass::instance->cacheManager, - &replacement_font->font.font, &replacement_face, - &replacement_font->size)<0) -#endif { eDebug("FTC_Manager_Lookup_Size failed!"); return; @@ -479,24 +558,17 @@ void eTextPara::setFont(Font *fnt, Font *replacement) } if (current_font) { -#ifdef HAVE_FREETYPE2 if ((FTC_Manager_LookupFace(fontRenderClass::instance->cacheManager, current_font->scaler.face_id, ¤t_face) < 0) || (FTC_Manager_LookupSize(fontRenderClass::instance->cacheManager, ¤t_font->scaler, ¤t_font->size) < 0)) -#else - if (FTC_Manager_Lookup_Size(fontRenderClass::instance->cacheManager, ¤t_font->font.font, ¤t_face, ¤t_font->size)<0) -#endif { eDebug("FTC_Manager_Lookup_Size failed!"); return; } } -#ifndef HAVE_FREETYPE2 - cache_current_font=¤t_font->font.font; -#endif previous=0; use_kerning=FT_HAS_KERNING(current_face); } @@ -504,14 +576,13 @@ void eTextPara::setFont(Font *fnt, Font *replacement) void shape (std::vector &string, const std::vector &text); -int eTextPara::renderString(const char *string, int rflags) +int eTextPara::renderString(const char *string, int rflags, int border) { singleLock s(ftlock); if (!current_font) return -1; -#ifdef HAVE_FREETYPE2 if ((FTC_Manager_LookupFace(fontRenderClass::instance->cacheManager, current_font->scaler.face_id, ¤t_face) < 0) || @@ -522,17 +593,6 @@ int eTextPara::renderString(const char *string, int rflags) eDebug("FTC_Manager_Lookup_Size failed!"); return -1; } -#else - if (¤t_font->font.font != cache_current_font) - { - if (FTC_Manager_Lookup_Size(fontRenderClass::instance->cacheManager, ¤t_font->font.font, ¤t_face, ¤t_font->size)<0) - { - eDebug("FTC_Manager_Lookup_Size failed!"); - return -1; - } - cache_current_font=¤t_font->font.font; - } -#endif if (!current_face) eFatal("eTextPara::renderString: no current_face"); @@ -596,59 +656,18 @@ int eTextPara::renderString(const char *string, int rflags) // now do the usual logical->visual reordering int size=uc_shape.size(); -#ifdef HAVE_FRIBIDI FriBidiCharType dir=FRIBIDI_TYPE_ON; - int lines=1; - int pos=0, spos=0; 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); - - bool line_open = false; - while(pos < size) - { - int incr=1; - bool line_end = false; - if (!line_open) - line_open = true; - switch((unsigned long)array[pos]) - { - case '\\': - if (pos+1 == size || (unsigned long)array[pos+1] != 'n') - break; - ++incr; - case 0x8A: - case 0xE08A: - case '\n': - line_end = true; - default: - break; - } - if (line_end || pos+incr >= size) { - int len = pos - spos; - if (len) - fribidi_log2vis(array+spos, len, &dir, target+spos, 0, 0, 0); - target[pos] = array[pos]; - if (incr > 1) - target[pos+1] = array[pos+1]; - spos = pos+incr; - ++lines; - line_open = false; - } - pos += incr; - } - - if (lines < 2) - fribidi_log2vis(array, size, &dir, target, 0, 0, 0); - + fribidi_log2vis(array, size, &dir, target, 0, 0, 0); uc_visual.assign(target, target+size); -#else - uc_visual=uc_shape; -#endif glyphs.reserve(size); - + + unsigned long newcolor = 0; + bool activate_newcolor = false; int nextflags = 0; for (std::vector::const_iterator i(uc_visual.begin()); @@ -677,6 +696,24 @@ int eTextPara::renderString(const char *string, int rflags) case 'r': i++; goto nprint; + case 'c': + { + char color[8]; + int codeidx; + for (codeidx = 0; codeidx < 8; codeidx++) + { + if ((i + 2 + codeidx) == uc_visual.end()) break; + color[codeidx] = (char)((*(i + 2 + codeidx)) & 0xff); + } + if (codeidx == 8) + { + newcolor = gRGB(color).argb(); + activate_newcolor = true; + isprintable = 0; + i += 1 + codeidx; + } + break; + } default: ; } @@ -732,28 +769,40 @@ nprint: isprintable=0; if (!index) eDebug("unicode U+%4lx not present", chr); else - appendGlyph(replacement_font, replacement_face, index, flags, rflags); + appendGlyph(replacement_font, replacement_face, index, flags, rflags, border, activate_newcolor, newcolor); } else - appendGlyph(current_font, current_face, index, flags, rflags); + appendGlyph(current_font, current_face, index, flags, rflags, border, activate_newcolor, newcolor); + + activate_newcolor = false; } } bboxValid=false; calc_bbox(); -#ifdef HAVE_FRIBIDI if (dir & FRIBIDI_MASK_RTL) + { realign(dirRight); -#endif + doTopBottomReordering=true; + } + + if (charCount) + { + lineOffsets.push_back(cursor.y()); + lineChars.push_back(charCount); + charCount=0; + } + return 0; } -void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground) +void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground, bool border) { + if (glyphs.empty()) return; + singleLock s(ftlock); if (!current_font) return; -#ifdef HAVE_FREETYPE2 if ((FTC_Manager_LookupFace(fontRenderClass::instance->cacheManager, current_font->scaler.face_id, ¤t_face) < 0) || @@ -764,103 +813,166 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons eDebug("FTC_Manager_Lookup_Size failed!"); return; } -#else - if (¤t_font->font.font != cache_current_font) - { - if (FTC_Manager_Lookup_Size(fontRenderClass::instance->cacheManager, ¤t_font->font.font, ¤t_face, ¤t_font->size)<0) - { - eDebug("FTC_Manager_Lookup_Size failed!"); - return; - } - cache_current_font=¤t_font->font.font; - } -#endif ePtr target; dc.getPixmap(target); gSurface *surface = target->surface; + gRGB currentforeground = foreground; - register int opcode; + register int opcode = -1; gColor *lookup8, lookup8_invert[16]; gColor *lookup8_normal=0; + __u16 lookup16_normal[16], lookup16_invert[16], *lookup16; __u32 lookup32_normal[16], lookup32_invert[16], *lookup32; - - if (surface->bpp == 8) - { - if (surface->clut.data) - { - lookup8_normal=getColor(surface->clut, background, foreground).lookup; - - int i; - for (i=0; i<16; ++i) - lookup8_invert[i] = lookup8_normal[i^0xF]; - - opcode=0; - } else - opcode=1; - } else if (surface->bpp == 32) - { - opcode=3; - for (int i=0; i<16; ++i) - { -#define BLEND(y, x, a) (y + (((x-y) * a)>>8)) - - unsigned char da = background.a, dr = background.r, dg = background.g, db = background.b; - int sa = i * 16; - if (sa < 256) - { - da = BLEND(background.a, foreground.a, sa) & 0xFF; - dr = BLEND(background.r, foreground.r, sa) & 0xFF; - dg = BLEND(background.g, foreground.g, sa) & 0xFF; - db = BLEND(background.b, foreground.b, sa) & 0xFF; - } -#undef BLEND - da ^= 0xFF; - lookup32_normal[i]=db | (dg << 8) | (dr << 16) | (da << 24);; - } - for (int i=0; i<16; ++i) - lookup32_invert[i]=lookup32_normal[i^0xF]; - } else - { - eWarning("can't render to %dbpp", surface->bpp); - return; - } - gRegion area(eRect(0, 0, surface->x, surface->y)); gRegion clip = dc.getClip() & area; int buffer_stride=surface->stride; - - for (unsigned int c = 0; c < clip.rects.size(); ++c) + + bool setcolor = true; + 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) { - for (glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i) + while(!line_chars) { - if (i->flags & GS_SOFTHYPHEN) - continue; + line_offs = *(line_offs_it++); + line_chars = *(line_chars_it++); + } + if (i->flags & GS_COLORCHANGE) + { + /* don't do colorchanges in borders */ + if (!border) + { + currentforeground = i->newcolor; + setcolor = true; + } + } + if (setcolor) + { + setcolor = false; + if (surface->bpp == 8) + { + if (surface->clut.data) + { + lookup8_normal=getColor(surface->clut, background, currentforeground).lookup; + + int i; + for (i=0; i<16; ++i) + lookup8_invert[i] = lookup8_normal[i^0xF]; - if (!(i->flags & GS_INVERT)) + opcode=0; + } else + opcode=1; + } else if (surface->bpp == 16) + { + opcode=2; + for (int i = 0; i != 16; ++i) + { +#define BLEND(y, x, a) (y + (((x-y) * a)>>8)) + unsigned char da = background.a, dr = background.r, dg = background.g, db = background.b; + int sa = i * 16; + if (sa < 256) + { + dr = BLEND(background.r, foreground.r, sa) & 0xFF; + dg = BLEND(background.g, foreground.g, sa) & 0xFF; + db = BLEND(background.b, foreground.b, sa) & 0xFF; + } +#undef BLEND +#if BYTE_ORDER == LITTLE_ENDIAN + lookup16_normal[i] = bswap_16(((db >> 3) << 11) | ((dg >> 2) << 5) | (dr >> 3)); +#else + 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]; + } else if (surface->bpp == 32) { - lookup8 = lookup8_normal; - lookup32 = lookup32_normal; + opcode=3; + for (int i=0; i<16; ++i) + { +#define BLEND(y, x, a) (y + (((x-y) * a)>>8)) + + unsigned char da = background.a, dr = background.r, dg = background.g, db = background.b; + int sa = i * 16; + if (sa < 256) + { + da = BLEND(background.a, currentforeground.a, sa) & 0xFF; + dr = BLEND(background.r, currentforeground.r, sa) & 0xFF; + dg = BLEND(background.g, currentforeground.g, sa) & 0xFF; + db = BLEND(background.b, currentforeground.b, sa) & 0xFF; + } +#undef BLEND + da ^= 0xFF; + lookup32_normal[i]=db | (dg << 8) | (dr << 16) | (da << 24);; + } + for (int i=0; i<16; ++i) + lookup32_invert[i]=lookup32_normal[i^0xF]; } else { - lookup8 = lookup8_invert; - lookup32 = lookup32_invert; + eWarning("can't render to %dbpp", surface->bpp); + return; } - + } + if (i->flags & GS_SOFTHYPHEN) + continue; + + if (!(i->flags & GS_INVERT)) + { + lookup8 = lookup8_normal; + lookup16 = lookup16_normal; + lookup32 = lookup32_normal; + } else + { + lookup8 = lookup8_invert; + lookup16 = lookup16_invert; + lookup32 = lookup32_invert; + } + + int rxbase, rybase; + __u8 *dbase; + __u8 *sbase; + int sxbase; + int sybase; + int pitch; + if (i->image) + { + FT_BitmapGlyph glyph = border ? (FT_BitmapGlyph)i->borderimage : (FT_BitmapGlyph)i->image; + if (!glyph->bitmap.buffer) continue; + rxbase = i->x + glyph->left + offset.x(); + rybase = (doTopBottomReordering ? line_offs : i->y) - glyph->top + offset.y(); + sbase = glyph->bitmap.buffer; + sxbase = glyph->bitmap.width; + sybase = glyph->bitmap.rows; + pitch = glyph->bitmap.pitch; + } + else + { 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(); - - __u8 *d=(__u8*)(surface->data)+buffer_stride*ry+rx*surface->bypp; - __u8 *s=glyph_bitmap->buffer; - register int sx=glyph_bitmap->width; - int sy=glyph_bitmap->height; + rxbase=i->x+glyph_bitmap->left + offset.x(); + rybase=(doTopBottomReordering ? line_offs : i->y) - glyph_bitmap->top + offset.y(); + sbase=glyph_bitmap->buffer; + sxbase=glyph_bitmap->width; + sybase=glyph_bitmap->height; + pitch = glyph_bitmap->pitch; + } + dbase = (__u8*)(surface->data)+buffer_stride*rybase+rxbase*surface->bypp; + for (unsigned int c = 0; c < clip.rects.size(); ++c) + { + int rx = rxbase, ry = rybase; + __u8 *d = dbase; + __u8 *s = sbase; + register int sx = sxbase; + int sy = sybase; if ((sy+ry) >= clip.rects[c].bottom()) sy=clip.rects[c].bottom()-ry; if ((sx+rx) >= clip.rects[c].right()) @@ -876,52 +988,94 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons if (ry < clip.rects[c].top()) { int diff=clip.rects[c].top()-ry; - s+=diff*glyph_bitmap->pitch; + s+=diff*pitch; sy-=diff; ry+=diff; d+=diff*buffer_stride; } - if (sx>0) - for (int ay=0; ay0) && (sy>0)) + { + int extra_source_stride = pitch - sx; + switch (opcode) { - if (!opcode) // 4bit lookup to 8bit + case 0: // 4bit lookup to 8bit + { + register int extra_buffer_stride = buffer_stride - sx; + register __u8 *td=d; + for (int ay = 0; ay < sy; ay++) { - register __u8 *td=d; register int ax; - for (ax=0; ax>4; if(b) - *td++=lookup8[b]; - else - td++; + *td=lookup8[b]; + ++td; } - } else if (opcode == 1) // 8bit direct + s += extra_source_stride; + td += extra_buffer_stride; + } + } + break; + case 1: // 8bit direct + { + register int extra_buffer_stride = buffer_stride - sx; + register __u8 *td=d; + for (int ay = 0; ay < sy; ay++) { - register __u8 *td=d; register int ax; for (ax=0; ax> 1) - sx; + register __u16 *td = (__u16*)d; + for (int ay = 0; ay != sy; ay++) + { + register int ax; + for (ax = 0; ax != sx; ax++) + { + register int b = (*s++) >> 4; + if (b) + *td = lookup16[b]; + ++td; + } + s += extra_source_stride; + td += extra_buffer_stride; + } + } + break; + case 3: // 32bit + { + register int extra_buffer_stride = (buffer_stride >> 2) - sx; + register __u32 *td=(__u32*)d; + for (int ay = 0; ay < sy; ay++) { - register __u32 *td=(__u32*)d; register int ax; for (ax=0; ax>4; if(b) - *td++=lookup32[b]; - else - td++; + *td=lookup32[b]; + ++td; } + s += extra_source_stride; + td += extra_buffer_stride; + } } - s+=glyph_bitmap->pitch-sx; - d+=buffer_stride; + break; + default: + break; } + } } } } @@ -1015,6 +1169,11 @@ void eTextPara::clear() current_font = 0; replacement_font = 0; + for (unsigned int i = 0; i < glyphs.size(); i++) + { + if (glyphs[i].image) FT_Done_Glyph(glyphs[i].image); + if (glyphs[i].borderimage) FT_Done_Glyph(glyphs[i].borderimage); + } glyphs.clear(); }