if (!transform) {
while (i < glyphs.numGlyphs) {
if (!glyphs.attributes[i].dontPrint) {
- positions[current].x = xpos + glyphs.offsets[i].x;
- positions[current].y = ypos + glyphs.offsets[i].y;
+ positions[current].x = xpos;
+ positions[current].y = ypos;
glyphs_out[current] = glyphs.glyphs[i];
xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
++current;
} else {
while (i < glyphs.numGlyphs) {
if (!glyphs.attributes[i].dontPrint) {
- QFixed gpos_x = xpos + glyphs.offsets[i].x;
- QFixed gpos_y = ypos + glyphs.offsets[i].y;
- QPointF gpos(gpos_x.toReal(), gpos_y.toReal());
+ QPointF gpos(xpos.toReal(), ypos.toReal());
gpos = gpos * matrix;
positions[current].x = QFixed::fromReal(gpos.x());
positions[current].y = QFixed::fromReal(gpos.y());
continue;
}
- QFixedPoint offset = g.offsets[i];
- advanceX += offset.x;
- advanceY += offset.y;
-
path->moveTo((advanceX + metrics.x).toReal(), (advanceY + metrics.y).toReal());
path->addRect(QRectF(0.0, 0.0, _size, _size));
path->closeSubpath();
*combiningClass = QUnicodeTables::combiningClass(ch);
}
-static void qHB_getGlyphMetrics(QFontEngine* fe, HB_Glyph glyph, HB_GlyphMetrics *metrics)
-{
- glyph_metrics_t m = fe->boundingBox(glyph);
- metrics->x = m.x.value();
- metrics->y = m.y.value();
- metrics->width = m.width.value();
- metrics->height = m.height.value();
- metrics->xOffset = m.xoff.value();
-}
-
-static HB_Fixed qHB_getGlyphAscent(QFontEngine* fe)
-{
- return fe->ascent().value();
-}
-
static void qHB_GetGlyphAdvances(QFontEngine* fe, const HB_Glyph *glyphs, uint32_t numGlyphs, HB_Fixed *advances, int flags)
{
QVarLengthGlyphLayoutArray qglyphs(numGlyphs);
int nmarks = glast - gfrom;
assert(nmarks > 0);
- HB_Glyph *glyphs = item->glyphs;
- HB_GlyphAttributes *attributes = item->attributes;
-
- HB_GlyphMetrics baseMetrics;
- qHB_getGlyphMetrics(item->font, glyphs[gfrom], &baseMetrics);
-
- if (item->item.script == HB_Script_Hebrew
- && (-baseMetrics.y) > baseMetrics.height)
- // we need to attach below the baseline, because of the hebrew iud.
- baseMetrics.height = -baseMetrics.y;
-
// qDebug("---> positionCluster: cluster from %d to %d", gfrom, glast);
// qDebug("baseInfo: %f/%f (%f/%f) off=%f/%f", baseInfo.x, baseInfo.y, baseInfo.width, baseInfo.height, baseInfo.xoff, baseInfo.yoff);
- HB_Fixed size = qHB_getGlyphAscent(item->font) / 10;
- HB_Fixed offsetBase = HB_FIXED_CONSTANT(1) + (size - HB_FIXED_CONSTANT(4)) / 4;
- if (size > HB_FIXED_CONSTANT(4))
- offsetBase += HB_FIXED_CONSTANT(4);
- else
- offsetBase += size;
- // qreal offsetBase = (size - 4) / 4 + qMin<qreal>(size, 4) + 1;
- // qDebug("offset = %f", offsetBase);
-
- HB_CombiningClass lastCmb = HB_Combining_NotOrdered;
- HB_GlyphMetrics attachmentRect;
- memset(&attachmentRect, 0, sizeof(attachmentRect));
-
for(int i = 1; i <= nmarks; i++) {
- HB_Glyph mark = glyphs[gfrom+i];
- HB_GlyphMetrics markMetrics;
- qHB_getGlyphMetrics(item->font, mark, &markMetrics);
- HB_FixedPoint p;
- p.x = p.y = 0;
- // qDebug("markInfo: %f/%f (%f/%f) off=%f/%f", markInfo.x, markInfo.y, markInfo.width, markInfo.height, markInfo.xoff, markInfo.yoff);
-
- HB_Fixed offset = offsetBase;
- HB_CombiningClass cmb = attributes[gfrom+i].combiningClass;
-
- // combining marks of different class don't interact. Reset the rectangle.
- if (cmb != lastCmb) {
- // qDebug("resetting rect");
- attachmentRect = baseMetrics;
- }
-
- switch(cmb) {
- case HB_Combining_DoubleBelow:
- // ### wrong in rtl context!
- case HB_Combining_BelowLeft:
- p.y += offset;
- case HB_Combining_Below:
- p.y += offset;
- case HB_Combining_BelowRight:
- p.y += offset;
- case HB_Combining_Left:
- p.x -= offset;
- case HB_Combining_Right:
- p.x += offset;
- case HB_Combining_DoubleAbove:
- // ### wrong in RTL context!
- case HB_Combining_AboveLeft:
- p.y -= offset;
- case HB_Combining_Above:
- p.y -= offset;
- case HB_Combining_AboveRight:
- p.y -= offset;
-
- case HB_Combining_IotaSubscript:
- default:
- break;
- }
- // qDebug("char=%x combiningClass = %d offset=%f/%f", mark, cmb, p.x(), p.y());
- markMetrics.x += p.x;
- markMetrics.y += p.y;
-
- HB_GlyphMetrics unitedAttachmentRect = attachmentRect;
- unitedAttachmentRect.x = HB_MIN(attachmentRect.x, markMetrics.x);
- unitedAttachmentRect.y = HB_MIN(attachmentRect.y, markMetrics.y);
- unitedAttachmentRect.width = HB_MAX(attachmentRect.x + attachmentRect.width, markMetrics.x + markMetrics.width) - unitedAttachmentRect.x;
- unitedAttachmentRect.height = HB_MAX(attachmentRect.y + attachmentRect.height, markMetrics.y + markMetrics.height) - unitedAttachmentRect.y;
- attachmentRect = unitedAttachmentRect;
-
- lastCmb = cmb;
- item->offsets[gfrom+i].x = p.x - baseMetrics.xOffset;
- item->offsets[gfrom+i].y = p.y;
item->advances[gfrom+i] = 0;
}
}
} HB_CharAttributes;
typedef struct {
- HB_Fixed x;
- HB_Fixed y;
-} HB_FixedPoint;
-
-typedef struct {
- HB_Fixed x, y;
- HB_Fixed width, height;
- HB_Fixed xOffset;
-} HB_GlyphMetrics;
-
-typedef struct {
uint32_t pos;
uint32_t length;
HB_Script script;
HB_Glyph *glyphs; /* output: <num_glyphs> indices of shaped glyphs */
HB_GlyphAttributes *attributes; /* output: <num_glyphs> glyph attributes */
HB_Fixed *advances; /* output: <num_glyphs> advances */
- HB_FixedPoint *offsets; /* output: <num_glyphs> offsets */
unsigned short *log_clusters; /* output: for each output glyph, the index in the input of the start of its logical cluster */
QFontEngine* font;
HB_CharAttributes *attributes);
Q_DECLARE_TYPEINFO(HB_GlyphAttributes, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(HB_FixedPoint, Q_PRIMITIVE_TYPE);
QT_END_NAMESPACE
void QTextEngine::shapeTextWithHarfbuzz(int item) const
{
Q_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));
- Q_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint));
QScriptItem &si = layoutData->items[item];
shaper_item.glyphs = g.glyphs;
shaper_item.attributes = g.attributes;
shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances_x);
- shaper_item.offsets = reinterpret_cast<HB_FixedPoint *>(g.offsets);
if (shaper_item.glyphIndicesPresent) {
for (uint32_t i = 0; i < shaper_item.initialGlyphCount; ++i)
struct QGlyphLayout
{
// init to 0 not needed, done when shaping
- QFixedPoint *offsets; // 8 bytes per element
HB_Glyph *glyphs; // 4 bytes per element
QFixed *advances_x; // 4 bytes per element
QGlyphJustification *justifications; // 4 bytes per element
inline explicit QGlyphLayout(char *address, int totalGlyphs)
{
- offsets = reinterpret_cast<QFixedPoint *>(address);
- int offset = totalGlyphs * sizeof(HB_FixedPoint);
- glyphs = reinterpret_cast<HB_Glyph *>(address + offset);
- offset += totalGlyphs * sizeof(HB_Glyph);
+ int offset = totalGlyphs * sizeof(HB_Glyph);
+ glyphs = reinterpret_cast<HB_Glyph *>(address);
advances_x = reinterpret_cast<QFixed *>(address + offset);
offset += totalGlyphs * sizeof(QFixed);
justifications = reinterpret_cast<QGlyphJustification *>(address + offset);
QGlyphLayout copy = *this;
copy.glyphs += position;
copy.advances_x += position;
- copy.offsets += position;
copy.justifications += position;
copy.attributes += position;
if (n == -1)
static inline int spaceNeededForGlyphLayout(int totalGlyphs) {
return totalGlyphs * (sizeof(HB_Glyph) + sizeof(HB_GlyphAttributes)
- + sizeof(QFixed) + sizeof(QFixedPoint)
- + sizeof(QGlyphJustification));
+ + sizeof(QFixed) + sizeof(QGlyphJustification));
}
inline QFixed effectiveAdvance(int item) const
inline void clear(int first = 0, int last = -1) {
if (last == -1)
last = numGlyphs;
- if (first == 0 && last == numGlyphs
- && reinterpret_cast<char *>(offsets + numGlyphs) == reinterpret_cast<char *>(glyphs)) {
- memset(offsets, 0, spaceNeededForGlyphLayout(numGlyphs));
+ if (first == 0 && last == numGlyphs) {
+ memset(glyphs, 0, spaceNeededForGlyphLayout(numGlyphs));
} else {
const int num = last - first;
- memset(offsets + first, 0, num * sizeof(QFixedPoint));
memset(glyphs + first, 0, num * sizeof(HB_Glyph));
memset(advances_x + first, 0, num * sizeof(QFixed));
memset(justifications + first, 0, num * sizeof(QGlyphJustification));
}
inline char *data() {
- return reinterpret_cast<char *>(offsets);
+ return reinterpret_cast<char *>(glyphs);
}
void grow(char *address, int totalGlyphs);
private:
void *buffer[(N * (sizeof(HB_Glyph) + sizeof(HB_GlyphAttributes)
- + sizeof(QFixed) + sizeof(QFixedPoint)
- + sizeof(QGlyphJustification)))
+ + sizeof(QFixed) + sizeof(QGlyphJustification)))
/ QT_POINTER_SIZE + 1];
};