From 91233f88a3b4dc392389fad1626c56ed0b3812a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 26 Feb 2014 09:33:43 +0100 Subject: [PATCH] Font: Work on support for spacing modes. * Change default spacing to B_BITMAP_SPACING. The BeBook does not document what the default spacing is, and I have no BeOS install handy to check. However, I believe that B_BITMAP_SPACING is what should be the default, since it gives the best visible result for the common use-case. In terms of implementation, there is no change, since spacing was ignored until now and the behavior was that of B_BITMAP_SPACING. This change could however break BeOS apps which assume B_CHAR_SPACING is the default and don't set it on new when they need it. Sample code in the BeBook however shows setting B_CHAR_SPACING on a newly created BFont. * Implement B_STRING_SPACING to do something sensible. The BeBook documentation is completely vague in what it is actually supposed to do. Given the possibilities of FreeType, I am implementing it to enable the use of kerning. Kerning optimizes the spacing between two glyphs, for example, it would decrease the spacing between "T" and "e" in the string "Test" for our default font. Untested. --- src/kits/interface/Font.cpp | 2 +- src/servers/app/ServerFont.cpp | 64 ++++++++----------- src/servers/app/ServerFont.h | 2 +- .../app/drawing/Painter/AGGTextRenderer.cpp | 5 +- .../app/drawing/Painter/AGGTextRenderer.h | 5 -- src/servers/app/font/GlyphLayoutEngine.h | 15 ++--- 6 files changed, 38 insertions(+), 55 deletions(-) diff --git a/src/kits/interface/Font.cpp b/src/kits/interface/Font.cpp index 4d9ef6ab30..796b6f5134 100644 --- a/src/kits/interface/Font.cpp +++ b/src/kits/interface/Font.cpp @@ -503,7 +503,7 @@ BFont::BFont() fShear(90.0), fRotation(0.0), fFalseBoldWidth(0.0), - fSpacing(B_CHAR_SPACING), + fSpacing(B_BITMAP_SPACING), fEncoding(B_UNICODE_UTF8), fFace(0), fFlags(0), diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index 3e25553b9a..5c0da7563c 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009, Haiku. + * Copyright 2001-2014, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -118,20 +118,20 @@ is_white_space(uint32 charCode) \param flags Style flags as defined in \param spacing String spacing flag as defined in */ -ServerFont::ServerFont(FontStyle& style, float size, - float rotation, float shear, float falseBoldWidth, - uint16 flags, uint8 spacing) - : fStyle(&style), - fSize(size), - fRotation(rotation), - fShear(shear), - fFalseBoldWidth(falseBoldWidth), - fBounds(0, 0, 0, 0), - fFlags(flags), - fSpacing(spacing), - fDirection(style.Direction()), - fFace(style.Face()), - fEncoding(B_UNICODE_UTF8) +ServerFont::ServerFont(FontStyle& style, float size, float rotation, + float shear, float falseBoldWidth, uint16 flags, uint8 spacing) + : + fStyle(&style), + fSize(size), + fRotation(rotation), + fShear(shear), + fFalseBoldWidth(falseBoldWidth), + fBounds(0, 0, 0, 0), + fFlags(flags), + fSpacing(spacing), + fDirection(style.Direction()), + fFace(style.Face()), + fEncoding(B_UNICODE_UTF8) { fStyle->Acquire(); } @@ -465,11 +465,9 @@ ServerFont::GetHasGlyphs(const char* string, int32 numBytes, if (!string || numBytes <= 0 || !hasArray) return B_BAD_DATA; - bool kerning = true; // TODO make this a property? - HasGlyphsConsumer consumer(hasArray); if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, - NULL, kerning, fSpacing)) + NULL, fSpacing)) return B_OK; return B_ERROR; @@ -513,12 +511,11 @@ ServerFont::GetEdges(const char* string, int32 numBytes, if (!string || numBytes <= 0 || !edges) return B_BAD_DATA; - bool kerning = true; // TODO make this a property? - EdgesConsumer consumer(edges, fSize); if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, - NULL, kerning, fSpacing)) + NULL, fSpacing)) { return B_OK; + } return B_ERROR; @@ -603,13 +600,12 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars, if (!string || numBytes <= 0 || !escapementArray) return B_BAD_DATA; - bool kerning = true; // TODO make this a property? - BPointEscapementConsumer consumer(escapementArray, offsetArray, numChars, fSize); if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, - &delta, kerning, fSpacing)) + &delta, fSpacing)) { return B_OK; + } return B_ERROR; } @@ -659,12 +655,11 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars, if (!string || numBytes <= 0 || !widthArray) return B_BAD_DATA; - bool kerning = true; // TODO make this a property? - WidthEscapementConsumer consumer(widthArray, numChars, fSize); if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, - &delta, kerning, fSpacing)) + &delta, fSpacing)) { return B_OK; + } return B_ERROR; } @@ -767,14 +762,13 @@ ServerFont::GetBoundingBoxes(const char* string, int32 numBytes, if (!string || numBytes <= 0 || !rectArray) return B_BAD_DATA; - bool kerning = true; // TODO make this a property? - Transformable transform(EmbeddedTransformation()); BoundingBoxConsumer consumer(transform, rectArray, asString); if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, - stringEscapement ? &delta : NULL, kerning, fSpacing)) + stringEscapement ? &delta : NULL, fSpacing)) { return B_OK; + } return B_ERROR; } @@ -788,8 +782,6 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[], if (!charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray) return B_BAD_DATA; - bool kerning = true; // TODO make this a property? - Transformable transform(EmbeddedTransformation()); for (int32 i = 0; i < numStrings; i++) { @@ -799,8 +791,9 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[], BoundingBoxConsumer consumer(transform, NULL, true); if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, - &delta, kerning, fSpacing)) + &delta, fSpacing)) { return B_ERROR; + } rectArray[i] = consumer.stringBoundingBox; } @@ -832,12 +825,11 @@ ServerFont::StringWidth(const char *string, int32 numBytes, if (!string || numBytes <= 0) return 0.0; - bool kerning = true; // TODO make this a property? - StringWidthConsumer consumer; if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, - deltaArray, kerning, fSpacing)) + deltaArray, fSpacing)) { return 0.0; + } return consumer.width; } diff --git a/src/servers/app/ServerFont.h b/src/servers/app/ServerFont.h index f162304c6e..b04a7e310a 100644 --- a/src/servers/app/ServerFont.h +++ b/src/servers/app/ServerFont.h @@ -32,7 +32,7 @@ class ServerFont { float shear = 90.0, float falseBoldWidth = 0.0, uint16 flags = 0, - uint8 spacing = B_CHAR_SPACING); + uint8 spacing = B_BITMAP_SPACING); ServerFont(const ServerFont& font); virtual ~ServerFont(); diff --git a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp index ad4598a8f8..5ce1f5cdc2 100644 --- a/src/servers/app/drawing/Painter/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/AGGTextRenderer.cpp @@ -59,7 +59,6 @@ AGGTextRenderer::AGGTextRenderer(renderer_subpix_type& subpixRenderer, fHinted(true), fAntialias(true), - fKerning(true), fEmbeddedTransformation(), fViewTransformation(viewTransformation) { @@ -365,7 +364,7 @@ AGGTextRenderer::RenderString(const char* string, uint32 length, transform, transformOffset, nextCharPos, *this); GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, delta, - fKerning, B_BITMAP_SPACING, NULL, cacheReference); + fFont.Spacing(), NULL, cacheReference); return transform.TransformBounds(renderer.Bounds()); } @@ -402,7 +401,7 @@ AGGTextRenderer::RenderString(const char* string, uint32 length, transform, transformOffset, nextCharPos, *this); GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, NULL, - fKerning, B_BITMAP_SPACING, offsets, cacheReference); + fFont.Spacing(), offsets, cacheReference); return transform.TransformBounds(renderer.Bounds()); } diff --git a/src/servers/app/drawing/Painter/AGGTextRenderer.h b/src/servers/app/drawing/Painter/AGGTextRenderer.h index d1521fdb9e..7dd8f94979 100644 --- a/src/servers/app/drawing/Painter/AGGTextRenderer.h +++ b/src/servers/app/drawing/Painter/AGGTextRenderer.h @@ -47,10 +47,6 @@ public: bool Antialiasing() const { return fAntialias; } - void SetKerning(bool kerning); - bool Kerning() const - { return fKerning; } - BRect RenderString(const char* utf8String, uint32 length, const BPoint& baseLine, const BRect& clippingFrame, bool dryRun, @@ -97,7 +93,6 @@ private: bool fHinted; // is glyph hinting active? bool fAntialias; - bool fKerning; Transformable fEmbeddedTransformation; // rotated or sheared font? agg::trans_affine& fViewTransformation; diff --git a/src/servers/app/font/GlyphLayoutEngine.h b/src/servers/app/font/GlyphLayoutEngine.h index 481cfb121c..6ed1d3ae60 100644 --- a/src/servers/app/font/GlyphLayoutEngine.h +++ b/src/servers/app/font/GlyphLayoutEngine.h @@ -1,5 +1,5 @@ /* - * Copyright 2007, Haiku. All rights reserved. + * Copyright 2007-2014, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -92,7 +92,6 @@ public: const char* utf8String, int32 length, const escapement_delta* delta = NULL, - bool kerning = true, uint8 spacing = B_BITMAP_SPACING, const BPoint* offsets = NULL, FontCacheReference* cacheReference = NULL); @@ -173,7 +172,7 @@ inline bool GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, const ServerFont& font, const char* utf8String, int32 length, - const escapement_delta* delta, bool kerning, uint8 spacing, + const escapement_delta* delta, uint8 spacing, const BPoint* offsets, FontCacheReference* _cacheReference) { // TODO: implement spacing modes @@ -212,7 +211,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, double advanceX = 0.0; double advanceY = 0.0; -// uint32 lastCharCode = 0; // Needed for kerning, see below + uint32 lastCharCode = 0; // Needed for kerning in B_STRING_SPACING mode uint32 charCode; int32 index = 0; bool writeLocked = false; @@ -225,10 +224,8 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, x = offsets[index].x; y = offsets[index].y; } else { -// TODO: Currently disabled, because it works much too slow (doesn't seem -// to be properly cached in FreeType.) -// if (kerning) -// entry->GetKerning(lastCharCode, charCode, &advanceX, &advanceY); + if (spacing == B_STRING_SPACING) + entry->GetKerning(lastCharCode, charCode, &advanceX, &advanceY); x += advanceX; y += advanceY; @@ -273,7 +270,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, } } -// lastCharCode = charCode; + lastCharCode = charCode; if (utf8String - start + 1 > length) break; }