diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index 7bf6421a7b..2119286c2c 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -192,6 +192,8 @@ ServerFont::operator=(const ServerFont& font) SetStyle(font.fStyle); + fFace = font.fFace; + return *this; } @@ -252,7 +254,7 @@ ServerFont::SetStyle(FontStyle* style) if (style && style != fStyle) { fStyle.SetTo(style, false); - fFace = fStyle->Face(); + fFace = fStyle->PreservedFace(fFace); fDirection = fStyle->Direction(); } } @@ -304,10 +306,8 @@ ServerFont::SetFamilyAndStyle(uint32 fontID) status_t ServerFont::SetFace(uint16 face) { - // TODO: This needs further investigation. The face variable is actually - // flags, but some of them are not enforcable at the same time. Also don't - // confuse the Be API "face" with the Freetype face, which is just an - // index in case a single font file exports multiple font faces. The + // Don't confuse the Be API "face" with the Freetype face, which is just + // an index in case a single font file exports multiple font faces. The // FontStyle class takes care of mapping the font style name to the Be // API face flags in FontStyle::_TranslateStyleToFace(). @@ -319,7 +319,7 @@ ServerFont::SetFace(uint16 face) style.SetTo(gFontManager->GetStyleByIndex(familyID, i), false); if (style == NULL) break; - if (style->Face() == face) + if (style->PreservedFace(face) == face) break; else style = NULL; @@ -331,6 +331,7 @@ ServerFont::SetFace(uint16 face) if (!style) return B_ERROR; + fFace = face; SetStyle(style); return B_OK; diff --git a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp index 6110cef95e..8d3bf05a60 100644 --- a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp @@ -9,7 +9,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -19,11 +22,6 @@ #define SHOW_GLYPH_BOUNDS 0 -#if SHOW_GLYPH_BOUNDS -# include -# include -#endif - #include "GlobalSubpixelSettings.h" #include "GlyphLayoutEngine.h" #include "IntRect.h" @@ -121,7 +119,7 @@ typedef agg::conv_transform class AGGTextRenderer::StringRenderer { public: StringRenderer(const IntRect& clippingFrame, bool dryRun, - bool subpixelAntiAliased, + bool subpixelAntiAliased, bool underscore, FontCacheEntry::TransformedOutline& transformedGlyph, FontCacheEntry::TransformedContourOutline& transformedContour, const Transformable& transform, @@ -135,6 +133,7 @@ public: fDryRun(dryRun), fSubpixelAntiAliased(subpixelAntiAliased), fVector(false), + fUnderscore(underscore), fBounds(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN), fNextCharPos(nextCharPos), @@ -171,6 +170,49 @@ public: } } + if (fUnderscore && !fDryRun) { + agg::path_storage p; + IntRect b = fBounds; + b.bottom = (int)y; + b.OffsetBy(fTransformOffset); + p.move_to(b.left + 0.5, b.bottom + 2.5); + p.line_to(b.right + 0.5, b.bottom + 2.5); + p.close_polygon(); + agg::conv_stroke ps(p); + ps.width(fRenderer.fFont.Size() / 12.0f); + if (fRenderer.fMaskedScanline != NULL) { + fRenderer.fRasterizer.add_path(ps); + agg::render_scanlines(fRenderer.fRasterizer, + *fRenderer.fMaskedScanline, fRenderer.fSolidRenderer); + } else if (fSubpixelAntiAliased) { + fRenderer.fSubpixRasterizer.add_path(ps); + agg::render_scanlines(fRenderer.fSubpixRasterizer, + fRenderer.fSubpixScanline, fRenderer.fSubpixRenderer); + } else { + /* + scanline_unpacked_type sl1; + scanline_unpacked_type sl2; + + rasterizer_type ras1; + rasterizer_type ras2; + + ras1.add_path(ps); + ras2.add_path(fTransformedContour); + + agg::render_scanlines(ras1, + sl1, fRenderer.fSolidRenderer); + agg::render_scanlines(ras2, + sl2, fRenderer.fSolidRenderer); + + agg::sbool_combine_shapes_aa(agg::sbool_a_minus_b, + ras1, ras2, sl1, sl2, fRenderer.fScanline, fRenderer.fSolidRenderer); + */ + fRenderer.fRasterizer.add_path(ps); + agg::render_scanlines(fRenderer.fRasterizer, + fRenderer.fScanline, fRenderer.fSolidRenderer); + } + } + if (fNextCharPos) { fNextCharPos->x = x; fNextCharPos->y = y; @@ -322,6 +364,7 @@ private: bool fDryRun; bool fSubpixelAntiAliased; bool fVector; + bool fUnderscore; IntRect fBounds; BPoint* fNextCharPos; @@ -358,8 +401,10 @@ AGGTextRenderer::RenderString(const char* string, uint32 length, transform.Transform(&transformOffset); IntRect clippingIntFrame(clippingFrame); + bool underscore = fFont.Face() & B_UNDERSCORE_FACE; + StringRenderer renderer(clippingIntFrame, dryRun, - gSubpixelAntialiasing && fAntialias, + gSubpixelAntialiasing && fAntialias, underscore, transformedOutline, transformedContourOutline, transform, transformOffset, nextCharPos, *this); @@ -395,8 +440,10 @@ AGGTextRenderer::RenderString(const char* string, uint32 length, transform.Transform(&transformOffset); IntRect clippingIntFrame(clippingFrame); + bool underscore = fFont.Face() & B_UNDERSCORE_FACE; + StringRenderer renderer(clippingIntFrame, dryRun, - gSubpixelAntialiasing && fAntialias, + gSubpixelAntialiasing && fAntialias, underscore, transformedOutline, transformedContourOutline, transform, transformOffset, nextCharPos, *this); diff --git a/src/servers/app/font/FontFamily.cpp b/src/servers/app/font/FontFamily.cpp index 32c5938b02..eef0ea0300 100644 --- a/src/servers/app/font/FontFamily.cpp +++ b/src/servers/app/font/FontFamily.cpp @@ -260,9 +260,12 @@ FontFamily::GetStyleByID(uint16 id) const FontStyle* FontFamily::GetStyleMatchingFace(uint16 face) const { - // TODO: support other faces (strike through, underlined, outlines...) + // Other face flags do not impact the font selection (they are applied + // during drawing) face &= B_BOLD_FACE | B_ITALIC_FACE | B_REGULAR_FACE | B_CONDENSED_FACE | B_LIGHT_FACE | B_HEAVY_FACE; + if (face == 0) + face = B_REGULAR_FACE; int32 count = fStyles.CountItems(); for (int32 i = 0; i < count; i++) { diff --git a/src/servers/app/font/FontStyle.cpp b/src/servers/app/font/FontStyle.cpp index f7bbe4f67a..878c62c394 100644 --- a/src/servers/app/font/FontStyle.cpp +++ b/src/servers/app/font/FontStyle.cpp @@ -188,7 +188,8 @@ uint16 FontStyle::PreservedFace(uint16 face) const { // TODO: make this better - face &= ~(B_REGULAR_FACE | B_BOLD_FACE | B_ITALIC_FACE); + face &= ~(B_REGULAR_FACE | B_BOLD_FACE | B_ITALIC_FACE | B_CONDENSED_FACE + | B_LIGHT_FACE | B_HEAVY_FACE); face |= Face(); return face;