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.
This commit is contained in:
Stephan Aßmus
2014-02-26 11:51:37 +01:00
parent 569eed2db5
commit 91233f88a3
6 changed files with 38 additions and 55 deletions
+1 -1
View File
@@ -503,7 +503,7 @@ BFont::BFont()
fShear(90.0), fShear(90.0),
fRotation(0.0), fRotation(0.0),
fFalseBoldWidth(0.0), fFalseBoldWidth(0.0),
fSpacing(B_CHAR_SPACING), fSpacing(B_BITMAP_SPACING),
fEncoding(B_UNICODE_UTF8), fEncoding(B_UNICODE_UTF8),
fFace(0), fFace(0),
fFlags(0), fFlags(0),
+28 -36
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2009, Haiku. * Copyright 2001-2014, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -118,20 +118,20 @@ is_white_space(uint32 charCode)
\param flags Style flags as defined in <Font.h> \param flags Style flags as defined in <Font.h>
\param spacing String spacing flag as defined in <Font.h> \param spacing String spacing flag as defined in <Font.h>
*/ */
ServerFont::ServerFont(FontStyle& style, float size, ServerFont::ServerFont(FontStyle& style, float size, float rotation,
float rotation, float shear, float falseBoldWidth, float shear, float falseBoldWidth, uint16 flags, uint8 spacing)
uint16 flags, uint8 spacing) :
: fStyle(&style), fStyle(&style),
fSize(size), fSize(size),
fRotation(rotation), fRotation(rotation),
fShear(shear), fShear(shear),
fFalseBoldWidth(falseBoldWidth), fFalseBoldWidth(falseBoldWidth),
fBounds(0, 0, 0, 0), fBounds(0, 0, 0, 0),
fFlags(flags), fFlags(flags),
fSpacing(spacing), fSpacing(spacing),
fDirection(style.Direction()), fDirection(style.Direction()),
fFace(style.Face()), fFace(style.Face()),
fEncoding(B_UNICODE_UTF8) fEncoding(B_UNICODE_UTF8)
{ {
fStyle->Acquire(); fStyle->Acquire();
} }
@@ -465,11 +465,9 @@ ServerFont::GetHasGlyphs(const char* string, int32 numBytes,
if (!string || numBytes <= 0 || !hasArray) if (!string || numBytes <= 0 || !hasArray)
return B_BAD_DATA; return B_BAD_DATA;
bool kerning = true; // TODO make this a property?
HasGlyphsConsumer consumer(hasArray); HasGlyphsConsumer consumer(hasArray);
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
NULL, kerning, fSpacing)) NULL, fSpacing))
return B_OK; return B_OK;
return B_ERROR; return B_ERROR;
@@ -513,12 +511,11 @@ ServerFont::GetEdges(const char* string, int32 numBytes,
if (!string || numBytes <= 0 || !edges) if (!string || numBytes <= 0 || !edges)
return B_BAD_DATA; return B_BAD_DATA;
bool kerning = true; // TODO make this a property?
EdgesConsumer consumer(edges, fSize); EdgesConsumer consumer(edges, fSize);
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
NULL, kerning, fSpacing)) NULL, fSpacing)) {
return B_OK; return B_OK;
}
return B_ERROR; return B_ERROR;
@@ -603,13 +600,12 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars,
if (!string || numBytes <= 0 || !escapementArray) if (!string || numBytes <= 0 || !escapementArray)
return B_BAD_DATA; return B_BAD_DATA;
bool kerning = true; // TODO make this a property?
BPointEscapementConsumer consumer(escapementArray, offsetArray, numChars, BPointEscapementConsumer consumer(escapementArray, offsetArray, numChars,
fSize); fSize);
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
&delta, kerning, fSpacing)) &delta, fSpacing)) {
return B_OK; return B_OK;
}
return B_ERROR; return B_ERROR;
} }
@@ -659,12 +655,11 @@ ServerFont::GetEscapements(const char* string, int32 numBytes, int32 numChars,
if (!string || numBytes <= 0 || !widthArray) if (!string || numBytes <= 0 || !widthArray)
return B_BAD_DATA; return B_BAD_DATA;
bool kerning = true; // TODO make this a property?
WidthEscapementConsumer consumer(widthArray, numChars, fSize); WidthEscapementConsumer consumer(widthArray, numChars, fSize);
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
&delta, kerning, fSpacing)) &delta, fSpacing)) {
return B_OK; return B_OK;
}
return B_ERROR; return B_ERROR;
} }
@@ -767,14 +762,13 @@ ServerFont::GetBoundingBoxes(const char* string, int32 numBytes,
if (!string || numBytes <= 0 || !rectArray) if (!string || numBytes <= 0 || !rectArray)
return B_BAD_DATA; return B_BAD_DATA;
bool kerning = true; // TODO make this a property?
Transformable transform(EmbeddedTransformation()); Transformable transform(EmbeddedTransformation());
BoundingBoxConsumer consumer(transform, rectArray, asString); BoundingBoxConsumer consumer(transform, rectArray, asString);
if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, if (GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
stringEscapement ? &delta : NULL, kerning, fSpacing)) stringEscapement ? &delta : NULL, fSpacing)) {
return B_OK; return B_OK;
}
return B_ERROR; return B_ERROR;
} }
@@ -788,8 +782,6 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
if (!charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray) if (!charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray)
return B_BAD_DATA; return B_BAD_DATA;
bool kerning = true; // TODO make this a property?
Transformable transform(EmbeddedTransformation()); Transformable transform(EmbeddedTransformation());
for (int32 i = 0; i < numStrings; i++) { for (int32 i = 0; i < numStrings; i++) {
@@ -799,8 +791,9 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
BoundingBoxConsumer consumer(transform, NULL, true); BoundingBoxConsumer consumer(transform, NULL, true);
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
&delta, kerning, fSpacing)) &delta, fSpacing)) {
return B_ERROR; return B_ERROR;
}
rectArray[i] = consumer.stringBoundingBox; rectArray[i] = consumer.stringBoundingBox;
} }
@@ -832,12 +825,11 @@ ServerFont::StringWidth(const char *string, int32 numBytes,
if (!string || numBytes <= 0) if (!string || numBytes <= 0)
return 0.0; return 0.0;
bool kerning = true; // TODO make this a property?
StringWidthConsumer consumer; StringWidthConsumer consumer;
if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes, if (!GlyphLayoutEngine::LayoutGlyphs(consumer, *this, string, numBytes,
deltaArray, kerning, fSpacing)) deltaArray, fSpacing)) {
return 0.0; return 0.0;
}
return consumer.width; return consumer.width;
} }
+1 -1
View File
@@ -32,7 +32,7 @@ class ServerFont {
float shear = 90.0, float shear = 90.0,
float falseBoldWidth = 0.0, float falseBoldWidth = 0.0,
uint16 flags = 0, uint16 flags = 0,
uint8 spacing = B_CHAR_SPACING); uint8 spacing = B_BITMAP_SPACING);
ServerFont(const ServerFont& font); ServerFont(const ServerFont& font);
virtual ~ServerFont(); virtual ~ServerFont();
@@ -59,7 +59,6 @@ AGGTextRenderer::AGGTextRenderer(renderer_subpix_type& subpixRenderer,
fHinted(true), fHinted(true),
fAntialias(true), fAntialias(true),
fKerning(true),
fEmbeddedTransformation(), fEmbeddedTransformation(),
fViewTransformation(viewTransformation) fViewTransformation(viewTransformation)
{ {
@@ -365,7 +364,7 @@ AGGTextRenderer::RenderString(const char* string, uint32 length,
transform, transformOffset, nextCharPos, *this); transform, transformOffset, nextCharPos, *this);
GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, delta, GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, delta,
fKerning, B_BITMAP_SPACING, NULL, cacheReference); fFont.Spacing(), NULL, cacheReference);
return transform.TransformBounds(renderer.Bounds()); return transform.TransformBounds(renderer.Bounds());
} }
@@ -402,7 +401,7 @@ AGGTextRenderer::RenderString(const char* string, uint32 length,
transform, transformOffset, nextCharPos, *this); transform, transformOffset, nextCharPos, *this);
GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, NULL, GlyphLayoutEngine::LayoutGlyphs(renderer, fFont, string, length, NULL,
fKerning, B_BITMAP_SPACING, offsets, cacheReference); fFont.Spacing(), offsets, cacheReference);
return transform.TransformBounds(renderer.Bounds()); return transform.TransformBounds(renderer.Bounds());
} }
@@ -47,10 +47,6 @@ public:
bool Antialiasing() const bool Antialiasing() const
{ return fAntialias; } { return fAntialias; }
void SetKerning(bool kerning);
bool Kerning() const
{ return fKerning; }
BRect RenderString(const char* utf8String, BRect RenderString(const char* utf8String,
uint32 length, const BPoint& baseLine, uint32 length, const BPoint& baseLine,
const BRect& clippingFrame, bool dryRun, const BRect& clippingFrame, bool dryRun,
@@ -97,7 +93,6 @@ private:
bool fHinted; bool fHinted;
// is glyph hinting active? // is glyph hinting active?
bool fAntialias; bool fAntialias;
bool fKerning;
Transformable fEmbeddedTransformation; Transformable fEmbeddedTransformation;
// rotated or sheared font? // rotated or sheared font?
agg::trans_affine& fViewTransformation; agg::trans_affine& fViewTransformation;
+6 -9
View File
@@ -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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -92,7 +92,6 @@ public:
const char* utf8String, const char* utf8String,
int32 length, int32 length,
const escapement_delta* delta = NULL, const escapement_delta* delta = NULL,
bool kerning = true,
uint8 spacing = B_BITMAP_SPACING, uint8 spacing = B_BITMAP_SPACING,
const BPoint* offsets = NULL, const BPoint* offsets = NULL,
FontCacheReference* cacheReference = NULL); FontCacheReference* cacheReference = NULL);
@@ -173,7 +172,7 @@ inline bool
GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer,
const ServerFont& font, const ServerFont& font,
const char* utf8String, int32 length, const char* utf8String, int32 length,
const escapement_delta* delta, bool kerning, uint8 spacing, const escapement_delta* delta, uint8 spacing,
const BPoint* offsets, FontCacheReference* _cacheReference) const BPoint* offsets, FontCacheReference* _cacheReference)
{ {
// TODO: implement spacing modes // TODO: implement spacing modes
@@ -212,7 +211,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer,
double advanceX = 0.0; double advanceX = 0.0;
double advanceY = 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; uint32 charCode;
int32 index = 0; int32 index = 0;
bool writeLocked = false; bool writeLocked = false;
@@ -225,10 +224,8 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer,
x = offsets[index].x; x = offsets[index].x;
y = offsets[index].y; y = offsets[index].y;
} else { } else {
// TODO: Currently disabled, because it works much too slow (doesn't seem if (spacing == B_STRING_SPACING)
// to be properly cached in FreeType.) entry->GetKerning(lastCharCode, charCode, &advanceX, &advanceY);
// if (kerning)
// entry->GetKerning(lastCharCode, charCode, &advanceX, &advanceY);
x += advanceX; x += advanceX;
y += advanceY; y += advanceY;
@@ -273,7 +270,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer,
} }
} }
// lastCharCode = charCode; lastCharCode = charCode;
if (utf8String - start + 1 > length) if (utf8String - start + 1 > length)
break; break;
} }