app_server: Implemented support for B_CHAR_SPACING.

It doesn't yield quiet the expected results, yet. When hinting is turned on,
FontEngine takes a measurement of the precise advance values for each
cached glyph by invoking FT_Load_Glyph() with the FT_LOAD_NO_HINTING flag,
before loading the glyph for real without that flag. In GlyphLayoutEngine.h,
the precise advance value is used for B_CHAR_SPACING. The intended result
is that glyphs are rendered hinted (according to global Appearance settings),
but spaced along the base-line with precise, unhinted advance values. An
application would use this for example to implement precise page or print
preview and also for zooming text without altering the placement of glyphs.
For Gobe Productive, problems can be observed, because we don't implement this
correctly, yet.
This commit is contained in:
Stephan Aßmus
2014-02-26 11:51:39 +01:00
parent a4655126c9
commit d9d14326ca
5 changed files with 41 additions and 7 deletions
+7 -4
View File
@@ -96,14 +96,16 @@ public:
GlyphCache* CacheGlyph(uint32 glyphIndex,
uint32 dataSize, glyph_data_type dataType, const agg::rect_i& bounds,
float advanceX, float advanceY, float insetLeft, float insetRight)
float advanceX, float advanceY, float preciseAdvanceX,
float preciseAdvanceY, float insetLeft, float insetRight)
{
GlyphCache* glyph = fGlyphTable.Lookup(glyphIndex);
if (glyph != NULL)
return NULL;
glyph = new(std::nothrow) GlyphCache(glyphIndex, dataSize, dataType,
bounds, advanceX, advanceY, insetLeft, insetRight);
bounds, advanceX, advanceY, preciseAdvanceX, preciseAdvanceY,
insetLeft, insetRight);
if (glyph == NULL || glyph->data == NULL) {
delete glyph;
return NULL;
@@ -293,7 +295,7 @@ FontCacheEntry::CreateGlyph(uint32 glyphCode, FontCacheEntry* fallbackEntry)
if (render_as_zero_width(glyphCode)) {
// cache and return a zero width glyph
return fGlyphCache->CacheGlyph(glyphCode, 0, glyph_data_invalid,
agg::rect_i(0, 0, -1, -1), 0, 0, 0, 0);
agg::rect_i(0, 0, -1, -1), 0, 0, 0, 0, 0, 0);
}
// reset to our engine
@@ -310,6 +312,7 @@ FontCacheEntry::CreateGlyph(uint32 glyphCode, FontCacheEntry* fallbackEntry)
glyph = fGlyphCache->CacheGlyph(glyphCode,
engine->DataSize(), engine->DataType(), engine->Bounds(),
engine->AdvanceX(), engine->AdvanceY(),
engine->PreciseAdvanceX(), engine->PreciseAdvanceY(),
engine->InsetLeft(), engine->InsetRight());
if (glyph != NULL)
@@ -326,7 +329,7 @@ FontCacheEntry::InitAdaptors(const GlyphCache* glyph,
GlyphGray8Adapter& gray8Adapter, GlyphPathAdapter& pathAdapter,
double scale)
{
if (!glyph)
if (glyph == NULL)
return;
switch(glyph->data_type) {
+5
View File
@@ -43,6 +43,7 @@
struct GlyphCache {
GlyphCache(uint32 glyphIndex, uint32 dataSize, glyph_data_type dataType,
const agg::rect_i& bounds, float advanceX, float advanceY,
float preciseAdvanceX, float preciseAdvanceY,
float insetLeft, float insetRight)
:
glyph_index(glyphIndex),
@@ -52,6 +53,8 @@ struct GlyphCache {
bounds(bounds),
advance_x(advanceX),
advance_y(advanceY),
precise_advance_x(preciseAdvanceX),
precise_advance_y(preciseAdvanceY),
inset_left(insetLeft),
inset_right(insetRight),
hash_link(NULL)
@@ -70,6 +73,8 @@ struct GlyphCache {
agg::rect_i bounds;
float advance_x;
float advance_y;
float precise_advance_x;
float precise_advance_y;
float inset_left;
float inset_right;
+16 -1
View File
@@ -624,7 +624,22 @@ FontEngine::PrepareGlyph(uint32 glyphIndex)
loadFlags |= fGlyphRendering == glyph_ren_subpix ?
FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_NORMAL;
fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags);
if (fHinting) {
// Load without hinting to get precise advance values
// for B_CHAR_SPACING
fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags
| FT_LOAD_NO_HINTING);
} else {
fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags);
}
fPreciseAdvanceX = int26p6_to_dbl(fFace->glyph->advance.x);
fPreciseAdvanceY = int26p6_to_dbl(fFace->glyph->advance.y);
if (fHinting) {
// Need to load again with hinting.
fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags);
}
if (fLastError != 0)
return false;
+6
View File
@@ -105,6 +105,10 @@ class FontEngine {
{ return fAdvanceX; }
double AdvanceY() const
{ return fAdvanceY; }
double PreciseAdvanceX() const
{ return fPreciseAdvanceX; }
double PreciseAdvanceY() const
{ return fPreciseAdvanceY; }
double InsetLeft() const
{ return fInsetLeft; }
double InsetRight() const
@@ -136,6 +140,8 @@ class FontEngine {
agg::rect_i fBounds;
double fAdvanceX;
double fAdvanceY;
double fPreciseAdvanceX;
double fPreciseAdvanceY;
double fInsetLeft;
double fInsetRight;
+7 -2
View File
@@ -253,8 +253,13 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer,
advanceY = 0;
} else {
// get next increment for pen position
advanceX = glyph->advance_x;
advanceY = glyph->advance_y;
if (spacing == B_CHAR_SPACING) {
advanceX = glyph->precise_advance_x;
advanceY = glyph->precise_advance_y;
} else {
advanceX = glyph->advance_x;
advanceY = glyph->advance_y;
}
// adjust for custom spacing
if (delta != NULL) {