Kaydet (Commit) 15f6a97d authored tarafından Khaled Hosny's avatar Khaled Hosny

Fix applying DX adjustments in CommonSalLayout

By overriding GetCharWidths() and ApplyDXArray() with a simpler and
saner implementation.

This fixes rendering of Awami Nastaliq, as well as subtending marks in
Amiri and potentially other bugs.

Breaks Kashida justification, will need to rewrite that one as well.

Change-Id: I843679e937f2881e77df61f5cbd9516b6df1b3b6
üst 66104ff9
......@@ -68,6 +68,9 @@ public:
bool LayoutText(ImplLayoutArgs&) override;
void DrawText(SalGraphics&) const override;
std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&) const override;
virtual bool GetCharWidths(DeviceCoordinate* pCharWidths) const override;
virtual void ApplyDXArray(ImplLayoutArgs&) override;
};
#endif
......@@ -326,7 +326,7 @@ public:
void AppendGlyph( const GlyphItem& );
void Reserve(int size) { m_GlyphItems.reserve(size + 1); }
virtual void AdjustLayout( ImplLayoutArgs& ) override;
void ApplyDXArray( ImplLayoutArgs& );
virtual void ApplyDXArray( ImplLayoutArgs& );
void Justify( DeviceCoordinate nNewWidth );
void KashidaJustify( long nIndex, int nWidth );
void ApplyAsianKerning(const OUString& rStr);
......@@ -352,7 +352,7 @@ protected:
virtual void DropGlyph( int nStart ) override;
virtual void Simplify( bool bIsBase ) override;
bool GetCharWidths( DeviceCoordinate* pCharWidths ) const;
virtual bool GetCharWidths( DeviceCoordinate* pCharWidths ) const;
std::vector<GlyphItem> m_GlyphItems;
......
......@@ -489,3 +489,66 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
return true;
}
bool CommonSalLayout::GetCharWidths(DeviceCoordinate* pCharWidths) const
{
int nCharCount = mnEndCharPos - mnMinCharPos;
for (int i = 0; i < nCharCount; ++i)
pCharWidths[i] = 0;
for (auto const& aGlyphItem : m_GlyphItems)
pCharWidths[aGlyphItem.mnCharPos - mnMinCharPos] += aGlyphItem.mnNewWidth;
return true;
}
void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs)
{
if (rArgs.mpDXArray == nullptr)
return;
int nCharCount = mnEndCharPos - mnMinCharPos;
std::unique_ptr<DeviceCoordinate[]> const pOldCharWidths(new DeviceCoordinate[nCharCount]);
std::unique_ptr<DeviceCoordinate[]> const pNewCharWidths(new DeviceCoordinate[nCharCount]);
// Get the natural character widths (i.e. before applying DX adjustments).
GetCharWidths(pOldCharWidths.get());
// Calculate the character widths after DX adjustments.
for (int i = 0; i < nCharCount; ++i)
{
if (i == 0)
pNewCharWidths[i] = rArgs.mpDXArray[i];
else
pNewCharWidths[i] = rArgs.mpDXArray[i] - rArgs.mpDXArray[i - 1];
}
// The accumulated difference in X position.
DeviceCoordinate nDelta = 0;
// Apply the DX adjustments to glyph positions and widths.
size_t i = 0;
while (i < m_GlyphItems.size())
{
int nCharPos = m_GlyphItems[i].mnCharPos - mnMinCharPos;
DeviceCoordinate nDiff = pNewCharWidths[nCharPos] - pOldCharWidths[nCharPos];
m_GlyphItems[i].maLinearPos.X() += nDelta;
size_t j = i;
// Apply the delta to other glyphs belonging to the same character.
while (++j < m_GlyphItems.size())
{
if (m_GlyphItems[j].mnCharPos != m_GlyphItems[i].mnCharPos)
break;
m_GlyphItems[j].maLinearPos.X() += nDelta;
}
// Increment the delta, the loop above makes sure we do so only once
// for every character not for every glyph (otherwise we would apply it
// multiple times for each glyphs belonging to the same character which
// is wrong since DX adjustments are character based).
nDelta += nDiff;
i = j;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment