rpms/firefox/F-7 firefox-1.5-pango-cursor-position-more.patch, NONE, 1.1 firefox-1.5-pango-justified-range.patch, NONE, 1.1 firefox-1.5-pango-underline.patch, NONE, 1.1 firefox-1.5-xft-rangewidth.patch, NONE, 1.1 firefox-2.0-pango-ligatures.patch, NONE, 1.1 firefox.spec, 1.184, 1.185
Martin Stransky (stransky)
fedora-extras-commits at redhat.com
Mon Jul 9 08:29:11 UTC 2007
- Previous message: rpms/mantis/F-7 .cvsignore, 1.6, 1.7 mantis-README.Fedora, 1.1, 1.2 mantis-httpd.conf, 1.2, 1.3 mantis.spec, 1.15, 1.16 sources, 1.11, 1.12
- Next message: rpms/hunspell-ca/devel .cvsignore, 1.2, 1.3 hunspell-ca.spec, 1.1, 1.2 sources, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: stransky
Update of /cvs/pkgs/rpms/firefox/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26332
Modified Files:
firefox.spec
Added Files:
firefox-1.5-pango-cursor-position-more.patch
firefox-1.5-pango-justified-range.patch
firefox-1.5-pango-underline.patch
firefox-1.5-xft-rangewidth.patch
firefox-2.0-pango-ligatures.patch
Log Message:
backported pango patches from FC6
firefox-1.5-pango-cursor-position-more.patch:
--- NEW FILE firefox-1.5-pango-cursor-position-more.patch ---
diff -pruN -x '.moz*' -x .deps -x 'firefox*' -x '*.mk' -x 'config*' -x dist -x build -x toolkit -x '*o' -x '*a' -x '*html' mozilla.orig/layout/generic/nsTextFrame.cpp mozilla/layout/generic/nsTextFrame.cpp
--- mozilla.orig/layout/generic/nsTextFrame.cpp 2006-08-26 13:33:35.000000000 +0900
+++ mozilla/layout/generic/nsTextFrame.cpp 2006-12-13 20:54:32.000000000 +0900
@@ -4261,12 +4261,10 @@ nsTextFrame::GetPointFromOffset(nsPresCo
if (tc) {
totalLength = tc->Text()->GetLength(); // raw value which includes whitespace
}
- if ((hitLength == textLength) && (inOffset = mContentLength) &&
- (mContentOffset + mContentLength == totalLength)) {
- // no need to re-measure when at the end of the last-in-flow
- }
+ if (hitLength > 0)
+ inRendContext->GetRangeWidth(paintBuffer.mBuffer, textLength, 0, hitLength, (PRUint32&)width);
else
- inRendContext->GetWidth(paintBuffer.mBuffer, hitLength, width);
+ width = 0;
}
if ((hitLength == textLength) && (TEXT_TRIMMED_WS & mState)) {
//
firefox-1.5-pango-justified-range.patch:
--- NEW FILE firefox-1.5-pango-justified-range.patch ---
diff -pruN -x '.moz*' -x .deps -x 'thunderbird*' -x '*.mk' -x 'config*' -x dist -x build -x toolkit -x '*o' -x '*a' -x '*html' -x 'firefox*' mozilla.orig/layout/generic/nsTextFrame.cpp mozilla/layout/generic/nsTextFrame.cpp
--- mozilla.orig/layout/generic/nsTextFrame.cpp 2006-12-20 12:15:38.000000000 +0900
+++ mozilla/layout/generic/nsTextFrame.cpp 2006-12-20 21:29:39.000000000 +0900
@@ -2973,15 +2973,16 @@ nsTextFrame::RenderString(nsIRenderingCo
nsIFontMetrics* lastFont = aTextStyle.mLastFont;
PRInt32 pendingCount;
- PRUnichar* runStart = bp;
+ PRUnichar* runStart = bp, *top = aBuffer;
nscoord charWidth, width = 0;
PRInt32 countSoFar = 0;
+ PRUint32 offset;
// Save the color we want to use for the text, since calls to
// PaintTextDecorations in this method will call SetColor() on the rendering
// context.
nscolor textColor;
aRenderingContext.GetColor(textColor);
- for (; --aLength >= 0; aBuffer++) {
+ for (offset = 0; offset < aLength; aBuffer++, offset++) {
nsIFontMetrics* nextFont;
nscoord glyphWidth = 0;
PRUnichar ch = *aBuffer;
@@ -3038,7 +3039,7 @@ nsTextFrame::RenderString(nsIRenderingCo
else if (ch == ' ') {
glyphWidth += aTextStyle.mSpaceWidth + aTextStyle.mWordSpacing + aTextStyle.mLetterSpacing;
}
- else if (IS_HIGH_SURROGATE(ch) && aLength > 0 &&
+ else if (IS_HIGH_SURROGATE(ch) && (offset + 1) < aLength &&
IS_LOW_SURROGATE(*(aBuffer+1))) {
// special handling for surrogate pair
@@ -3046,7 +3047,7 @@ nsTextFrame::RenderString(nsIRenderingCo
glyphWidth += charWidth + aTextStyle.mLetterSpacing;
// copy the surrogate low
*bp++ = ch;
- --aLength;
+ offset++;
aBuffer++;
ch = *aBuffer;
// put the width into the space buffer
@@ -3058,10 +3059,10 @@ nsTextFrame::RenderString(nsIRenderingCo
glyphWidth = 0;
}
else {
- aRenderingContext.GetWidth(ch, charWidth);
+ aRenderingContext.GetRangeWidth(top, aLength, offset, offset + 1, (PRUint32&)charWidth);
glyphWidth += charWidth + aTextStyle.mLetterSpacing;
}
- if (justifying && (!isEndOfLine || aLength > 0)
+ if (justifying && (!isEndOfLine || (offset + 1) < aLength)
&& IsJustifiableCharacter(ch, isCJ)) {
glyphWidth += aTextStyle.mExtraSpacePerJustifiableCharacter;
if ((PRUint32)--aTextStyle.mNumJustifiableCharacterToRender
firefox-1.5-pango-underline.patch:
--- NEW FILE firefox-1.5-pango-underline.patch ---
diff -pruN -x '.moz*' -x .deps -x 'thunderbird*' -x '*.mk' -x 'config*' -x dist -x build -x toolkit -x '*o' -x '*a' -x '*html' mozilla.orig/layout/generic/nsTextFrame.cpp mozilla/layout/generic/nsTextFrame.cpp
--- mozilla.orig/layout/generic/nsTextFrame.cpp 2006-12-20 12:53:26.000000000 +0900
+++ mozilla/layout/generic/nsTextFrame.cpp 2006-12-20 15:43:14.000000000 +0900
@@ -2097,11 +2097,11 @@ nsTextFrame::PaintTextDecorations(nsIRen
nsRect rect = GetRect();
while(aDetails){
const nscoord* sp= aSpacing;
- PRInt32 startOffset = 0;
- PRInt32 textWidth = 0;
- PRInt32 start = PR_MAX(0,(aDetails->mStart - (PRInt32)aIndex));
- PRInt32 end = PR_MIN((PRInt32)aLength,(aDetails->mEnd - (PRInt32)aIndex));
- PRInt32 i;
+ PRUint32 startOffset = 0;
+ PRUint32 textWidth = 0;
+ PRUint32 start = PR_MAX(0,(aDetails->mStart - (PRInt32)aIndex));
+ PRUint32 end = PR_MIN((PRInt32)aLength,(aDetails->mEnd - (PRInt32)aIndex));
+ PRUint32 i;
if ((start < end) && ((aLength - start) > 0))
{
//aDetails allready processed to have offsets from frame start not content offsets
@@ -2117,7 +2117,7 @@ nsTextFrame::PaintTextDecorations(nsIRen
}
}
else
- aRenderingContext.GetWidth(aText, start, startOffset);
+ aRenderingContext.GetRangeWidth(aText, aLength, 0, start, startOffset);
}
if (sp){
for (i = start; i < end;i ++){
@@ -2125,8 +2125,7 @@ nsTextFrame::PaintTextDecorations(nsIRen
}
}
else
- aRenderingContext.GetWidth(aText + start,
- PRUint32(end - start), textWidth);
+ aRenderingContext.GetRangeWidth(aText, aLength, start, end, textWidth);
}
nscoord offset, size;
firefox-1.5-xft-rangewidth.patch:
--- NEW FILE firefox-1.5-xft-rangewidth.patch ---
diff -pruN -x '.moz*' -x .libs -x .deps -x dist -x 'config*' -x 'firefox*' -x '*a' -x '*so' -x '*o' -x build -x '*html' mozilla.orig/gfx/src/gtk/nsFontMetricsXft.cpp mozilla/gfx/src/gtk/nsFontMetricsXft.cpp
--- mozilla.orig/gfx/src/gtk/nsFontMetricsXft.cpp 2006-04-25 08:58:36.000000000 +0900
+++ mozilla/gfx/src/gtk/nsFontMetricsXft.cpp 2007-02-08 01:50:05.000000000 +0900
@@ -227,10 +227,14 @@ static nsresult EnumFontsXft (nsIAto
static void ConvertCharToUCS4 (const char *aString,
PRUint32 aLength,
+ PRUint32 aStart,
+ PRUint32 aEnd,
nsAutoFcChar32Buffer &aOutBuffer,
PRUint32 *aOutLen);
static void ConvertUnicharToUCS4 (const PRUnichar *aString,
PRUint32 aLength,
+ PRUint32 aStart,
+ PRUint32 aEnd,
nsAutoFcChar32Buffer &aOutBuffer,
PRUint32 *aOutLen);
static nsresult ConvertUCS4ToCustom (FcChar32 *aSrc, PRUint32 aSrcLen,
@@ -507,7 +511,7 @@ nsFontMetricsXft::GetWidth(const PRUnich
return NS_OK;
}
- gint rawWidth = RawGetWidth(aString, aLength);
+ gint rawWidth = RawGetWidth(aString, aLength, 0, aLength);
float f;
f = mDeviceContext->DevUnitsToAppUnits();
@@ -533,7 +537,7 @@ nsFontMetricsXft::GetTextDimensions(cons
return NS_OK;
nsresult rv;
- rv = EnumerateGlyphs(aString, aLength,
+ rv = EnumerateGlyphs(aString, aLength, 0, aLength,
&nsFontMetricsXft::TextDimensionsCallback,
&aDimensions);
@@ -608,7 +612,7 @@ nsFontMetricsXft::DrawString(const char
nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
data.drawBuffer = &drawBuffer;
- return EnumerateGlyphs(aString, aLength,
+ return EnumerateGlyphs(aString, aLength, 0, aLength,
&nsFontMetricsXft::DrawStringCallback, &data);
}
@@ -638,7 +642,7 @@ nsFontMetricsXft::DrawString(const PRUni
nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
data.drawBuffer = &drawBuffer;
- return EnumerateGlyphs(aString, aLength,
+ return EnumerateGlyphs(aString, aLength, 0, aLength,
&nsFontMetricsXft::DrawStringCallback, &data);
}
@@ -662,7 +666,7 @@ nsFontMetricsXft::GetBoundingMetrics(con
data.firstTime = PR_TRUE;
nsresult rv;
- rv = EnumerateGlyphs(aString, aLength,
+ rv = EnumerateGlyphs(aString, aLength, 0, aLength,
&nsFontMetricsXft::BoundingMetricsCallback, &data);
NS_ENSURE_SUCCESS(rv, rv);
@@ -700,7 +704,7 @@ nsFontMetricsXft::GetBoundingMetrics(con
data.firstTime = PR_TRUE;
nsresult rv;
- rv = EnumerateGlyphs(aString, aLength,
+ rv = EnumerateGlyphs(aString, aLength, 0, aLength,
&nsFontMetricsXft::BoundingMetricsCallback, &data);
NS_ENSURE_SUCCESS(rv, rv);
@@ -758,7 +762,17 @@ nsFontMetricsXft::GetRangeWidth(const PR
PRUint32 aEnd,
PRUint32 &aWidth)
{
- return NS_ERROR_NOT_IMPLEMENTED;
+ if (!aLength) {
+ aWidth = 0;
+ return NS_OK;
+ }
+
+ gint rawWidth = RawGetWidth(aText, aLength, aStart, aEnd);
+ float f = mDeviceContext->DevUnitsToAppUnits();
+
+ aWidth = NSToCoordRound(rawWidth * f);
+
+ return NS_OK;
}
nsresult
@@ -768,7 +782,17 @@ nsFontMetricsXft::GetRangeWidth(const ch
PRUint32 aEnd,
PRUint32 &aWidth)
{
- return NS_ERROR_NOT_IMPLEMENTED;
+ if (!aLength) {
+ aWidth = 0;
+ return NS_OK;
+ }
+
+ gint rawWidth = RawGetWidth(aText, aLength, aStart, aEnd);
+ float f = mDeviceContext->DevUnitsToAppUnits();
+
+ aWidth = NSToCoordRound(rawWidth * f);
+
+ return NS_OK;
}
PRUint32
@@ -850,12 +874,12 @@ nsFontMetricsXft::CacheFontMetrics(void)
// mSpaceWidth (width of a space)
gint rawWidth;
PRUnichar unispace(' ');
- rawWidth = RawGetWidth(&unispace, 1);
+ rawWidth = RawGetWidth(&unispace, 1, 0, 1);
mSpaceWidth = NSToCoordRound(rawWidth * f);
// mAveCharWidth (width of an 'average' char)
PRUnichar xUnichar('x');
- rawWidth = RawGetWidth(&xUnichar, 1);
+ rawWidth = RawGetWidth(&xUnichar, 1, 0, 1);
mAveCharWidth = NSToCoordRound(rawWidth * f);
// mXHeight (height of an 'x' character)
@@ -1226,12 +1250,27 @@ nsFontMetricsXft::DoMatch(PRBool aMatchA
}
gint
-nsFontMetricsXft::RawGetWidth(const PRUnichar* aString, PRUint32 aLength)
+nsFontMetricsXft::RawGetWidth(const PRUnichar* aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd)
+{
+ nscoord width = 0;
+ nsresult rv;
+
+ rv = EnumerateGlyphs(aString, aLength, aStart, aEnd,
+ &nsFontMetricsXft::GetWidthCallback, &width);
+
+ if (NS_FAILED(rv))
+ width = 0;
+
+ return width;
+}
+
+gint
+nsFontMetricsXft::RawGetWidth(const char* aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd)
{
nscoord width = 0;
nsresult rv;
- rv = EnumerateGlyphs(aString, aLength,
+ rv = EnumerateGlyphs(aString, aLength, aStart, aEnd,
&nsFontMetricsXft::GetWidthCallback, &width);
if (NS_FAILED(rv))
@@ -1457,6 +1496,8 @@ nsFontMetricsXft::EnumerateXftGlyphs(con
nsresult
nsFontMetricsXft::EnumerateGlyphs(const PRUnichar *aString,
PRUint32 aLen,
+ PRUint32 aStart,
+ PRUint32 aEnd,
GlyphEnumeratorCallback aCallback,
void *aCallbackData)
{
@@ -1465,7 +1506,7 @@ nsFontMetricsXft::EnumerateGlyphs(const
NS_ENSURE_TRUE(aLen, NS_OK);
- ConvertUnicharToUCS4(aString, aLen, charBuffer, &len);
+ ConvertUnicharToUCS4(aString, aLen, aStart, aEnd, charBuffer, &len);
if (!len)
return NS_ERROR_OUT_OF_MEMORY;
@@ -1475,6 +1516,8 @@ nsFontMetricsXft::EnumerateGlyphs(const
nsresult
nsFontMetricsXft::EnumerateGlyphs(const char *aString,
PRUint32 aLen,
+ PRUint32 aStart,
+ PRUint32 aEnd,
GlyphEnumeratorCallback aCallback,
void *aCallbackData)
{
@@ -1484,7 +1527,7 @@ nsFontMetricsXft::EnumerateGlyphs(const
NS_ENSURE_TRUE(aLen, NS_OK);
// Convert the incoming string into an array of UCS4 chars
- ConvertCharToUCS4(aString, aLen, charBuffer, &len);
+ ConvertCharToUCS4(aString, aLen, aStart, aEnd, charBuffer, &len);
if (!len)
return NS_ERROR_OUT_OF_MEMORY;
@@ -2343,7 +2386,7 @@ EnumFontsXft(nsIAtom* aLangGroup, const
/* static */
void
-ConvertCharToUCS4(const char *aString, PRUint32 aLength,
+ConvertCharToUCS4(const char *aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd,
nsAutoFcChar32Buffer &aOutBuffer, PRUint32 *aOutLen)
{
*aOutLen = 0;
@@ -2352,19 +2395,21 @@ ConvertCharToUCS4(const char *aString, P
if (!aOutBuffer.EnsureElemCapacity(aLength))
return;
outBuffer = aOutBuffer.get();
+ if (aEnd > aLength)
+ aEnd = aLength;
- for (PRUint32 i = 0; i < aLength; ++i) {
- outBuffer[i] = PRUint8(aString[i]); // to convert char >= 0x80 correctly
+ for (PRUint32 i = aStart; i < aLength && i < aEnd; ++i) {
+ outBuffer[i - aStart] = PRUint8(aString[i]); // to convert char >= 0x80 correctly
}
- *aOutLen = aLength;
+ *aOutLen = aEnd - aStart;
}
// Convert the incoming string into an array of UCS4 chars
/* static */
void
-ConvertUnicharToUCS4(const PRUnichar *aString, PRUint32 aLength,
+ConvertUnicharToUCS4(const PRUnichar *aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd,
nsAutoFcChar32Buffer &aOutBuffer, PRUint32 *aOutLen)
{
*aOutLen = 0;
@@ -2378,7 +2423,7 @@ ConvertUnicharToUCS4(const PRUnichar *aS
// Walk the passed in string looking for surrogates to convert to
// their full ucs4 representation.
- for (PRUint32 i = 0; i < aLength; ++i) {
+ for (PRUint32 i = aStart; i < aLength && i < aEnd; ++i) {
PRUnichar c = aString[i];
// Optimized for the non-surrogate case
@@ -2693,12 +2738,12 @@ ConvertUCS4ToCustom(FcChar32 *aSrc, PRU
#endif
// Convert 16bit custom font codes to UCS4
ConvertUnicharToUCS4(NS_REINTERPRET_CAST(PRUnichar *, med),
- medLen >> 1, aResult, &aDestLen);
+ medLen >> 1, 0, medLen >> 1, aResult, &aDestLen);
rv = aDestLen ? rv : NS_ERROR_OUT_OF_MEMORY;
}
else {
// Convert 8bit custom font codes to UCS4
- ConvertCharToUCS4(med, medLen, aResult, &aDestLen);
+ ConvertCharToUCS4(med, medLen, 0, medLen, aResult, &aDestLen);
rv = aDestLen ? rv : NS_ERROR_OUT_OF_MEMORY;
}
diff -pruN -x '.moz*' -x .libs -x .deps -x dist -x 'config*' -x 'firefox*' -x '*a' -x '*so' -x '*o' -x build -x '*html' mozilla.orig/gfx/src/gtk/nsFontMetricsXft.h mozilla/gfx/src/gtk/nsFontMetricsXft.h
--- mozilla.orig/gfx/src/gtk/nsFontMetricsXft.h 2005-05-03 05:48:30.000000000 +0900
+++ mozilla/gfx/src/gtk/nsFontMetricsXft.h 2007-02-08 01:38:27.000000000 +0900
@@ -259,7 +259,13 @@ private:
void DoMatch (PRBool aMatchAll);
gint RawGetWidth (const PRUnichar* aString,
- PRUint32 aLength);
+ PRUint32 aLength,
+ PRUint32 aStart,
+ PRUint32 aEnd);
+ gint RawGetWidth (const char* aString,
+ PRUint32 aLength,
+ PRUint32 aStart,
+ PRUint32 aEnd);
nsresult SetupMiniFont (void);
nsresult DrawUnknownGlyph (FcChar32 aChar,
nscoord aX,
@@ -272,10 +278,14 @@ private:
void *aCallbackData);
nsresult EnumerateGlyphs (const char *aString,
PRUint32 aLen,
+ PRUint32 aStart,
+ PRUint32 aEnd,
GlyphEnumeratorCallback aCallback,
void *aCallbackData);
nsresult EnumerateGlyphs (const PRUnichar *aString,
PRUint32 aLen,
+ PRUint32 aStart,
+ PRUint32 aEnd,
GlyphEnumeratorCallback aCallback,
void *aCallbackData);
void PrepareToDraw (nsRenderingContextGTK *aContext,
firefox-2.0-pango-ligatures.patch:
--- NEW FILE firefox-2.0-pango-ligatures.patch ---
--- mozilla.back/gfx/src/gtk/nsFontMetricsPango.cpp.orig 2007-06-28 14:44:31.000000000 +0200
+++ mozilla.back/gfx/src/gtk/nsFontMetricsPango.cpp 2007-06-28 15:48:04.000000000 +0200
@@ -21,6 +21,8 @@
* are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Christopher Blizzard <blizzard at mozilla.org>
+ * Behdad Esfahbod <behdad at behdad.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -36,6 +38,10 @@
*
* ***** END LICENSE BLOCK ***** */
+#define PANGO_ENABLE_BACKEND
+
+#include "nsFontMetricsPango.h"
+
#include <strings.h>
#include "nsFont.h"
#include "nsIDeviceContext.h"
@@ -43,27 +49,37 @@
#include "nsIPref.h"
#include "nsServiceManagerUtils.h"
-#define PANGO_ENABLE_BACKEND
-#define PANGO_ENABLE_ENGINE
-
-#include "nsFontMetricsPango.h"
-#include "nsRenderingContextGTK.h"
-#include "nsDeviceContextGTK.h"
#include "nsFontConfigUtils.h"
#include "nsUnicharUtils.h"
#include "nsQuickSort.h"
#include "nsFontConfigUtils.h"
+#include "mozilla-decoder.h"
+
+#define FORCE_PR_LOG
+#include "prlog.h"
+
#include <fontconfig/fontconfig.h>
+#include <freetype/tttables.h>
+
+#include <pango/pango.h>
+#include <pango/pangofc-font.h>
+
+#ifdef PSPANGO
+#include <pango/pangoft2.h>
+#include "nsRenderingContextPS.h"
+#include "nsDeviceContextPS.h"
+#include "nsType1.h"
+#else
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
-#include <freetype/tttables.h>
+#include "nsRenderingContextGTK.h"
+#include "nsDeviceContextGTK.h"
+#endif
+
-#include "mozilla-decoder.h"
-#define FORCE_PR_LOG
-#include "prlog.h"
// Globals
@@ -108,6 +124,49 @@ static nsresult EnumFontsPango (nsI
PRUint32* aCount, PRUnichar*** aResult);
static int CompareFontNames (const void* aArg1, const void* aArg2,
void* aClosure);
+static void utf16_to_utf8 (const PRUnichar* aString, PRUint32 aLength,
+ char *&text, gint &text_len);
+
+#ifdef PSPANGO
+static void
+default_substitute (FcPattern *pattern,
+ gpointer data)
+{
+ FcPatternDel (pattern, FC_HINTING);
+ FcPatternAddBool (pattern, FC_HINTING, 0);
+}
+#endif
+
+static PangoFontMap *
+get_fontmap (void)
+{
+ static PangoFontMap *fontmap = NULL;
+
+ if (!fontmap) {
+#ifdef PSPANGO
+ fontmap = pango_ft2_font_map_new ();
+ pango_ft2_font_map_set_resolution ((PangoFT2FontMap *)fontmap, 72., 72.);
+ pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, default_substitute, NULL, NULL);
+#else
+ PangoContext* context = gdk_pango_context_get ();
+ fontmap = pango_context_get_font_map (context);
+ g_object_unref (context);
+#endif
+ }
+
+ return fontmap;
+}
+
+static PangoContext *
+get_context (void)
+{
+#ifdef PSPANGO
+ return pango_ft2_font_map_create_context ((PangoFT2FontMap *) get_fontmap ());
+#else
+ return gdk_pango_context_get();
+#endif
+}
+
nsFontMetricsPango::nsFontMetricsPango()
{
@@ -169,14 +228,20 @@ nsFontMetricsPango::Init(const nsFont& a
mLangGroup = aLangGroup;
// Hang on to the device context
+#ifdef PSPANGO
+ mDeviceContext = (nsDeviceContextPS *)aContext;
+#else
mDeviceContext = aContext;
+#endif
mPointSize = NSTwipsToFloatPoints(mFont.size);
+#ifndef PSPANGO
// Make sure to clamp the pixel size to something reasonable so we
// don't make the X server blow up.
nscoord screenPixels = gdk_screen_height();
mPointSize = PR_MIN(screenPixels * FONT_MAX_FONT_SCALE, mPointSize);
+#endif
// enumerate over the font names passed in
mFont.EnumerateFamilies(nsFontMetricsPango::EnumFontCallback, this);
@@ -329,7 +394,7 @@ nsFontMetricsPango::CacheFontMetrics(voi
// mPangoSpaceWidth
PangoLayout *layout = pango_layout_new(mPangoContext);
- pango_layout_set_text(layout, " ", 1);
+ pango_layout_set_text(layout, " ", -1);
int pswidth, psheight;
pango_layout_get_size(layout, &pswidth, &psheight);
mPangoSpaceWidth = pswidth;
@@ -337,14 +402,14 @@ nsFontMetricsPango::CacheFontMetrics(voi
// mSpaceWidth (width of a space)
nscoord tmpWidth;
- GetWidth(" ", 1, tmpWidth, NULL);
+ GetWidth(" ", 1, tmpWidth CONTEXT_ARG_NULL);
mSpaceWidth = tmpWidth;
// mAveCharWidth (width of an 'average' char)
// XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
//rawWidth = extents.width;
//mAveCharWidth = NSToCoordRound(rawWidth * f);
- GetWidth("x", 1, tmpWidth, NULL);
+ GetWidth("x", 1, tmpWidth CONTEXT_ARG_NULL);
mAveCharWidth = tmpWidth;
// mXHeight (height of an 'x' character)
@@ -460,130 +525,96 @@ nsFontMetricsPango::GetFontHandle(nsFont
// nsIFontMetricsPango impl
-nsresult
-nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
- nscoord& aWidth,
- nsRenderingContextGTK *aContext)
+#ifdef PSPANGO
+NS_IMETHODIMP
+nsFontMetricsPSPango::GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength)
{
- PangoLayout *layout = pango_layout_new(mPangoContext);
-
- pango_layout_set_text(layout, aString, aLength);
+ return GetWidth (String, (PRUint32) aLength, aWidth CONTEXT_ARG_NULL);
+}
- if (mPangoSpaceWidth)
- FixupSpaceWidths(layout, aString);
+NS_IMETHODIMP
+nsFontMetricsPSPango::GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength)
+{
+ return GetWidth (aString, (PRUint32)aLength, aWidth, NULL CONTEXT_ARG_NULL);
+}
+#endif
+nsresult
+nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
+ nscoord& aWidth
+ CONTEXT_ARG_DEF)
+{
int width, height;
-
+ PangoLayout *layout = GetLayout(aString, aLength);
pango_layout_get_size(layout, &width, &height);
-
g_object_unref(layout);
- float f;
- f = mDeviceContext->DevUnitsToAppUnits();
+ float f = mDeviceContext->DevUnitsToAppUnits();
aWidth = NSToCoordRound(width * f / PANGO_SCALE);
- // printf("GetWidth (char *) %d\n", aWidth);
-
return NS_OK;
}
nsresult
nsFontMetricsPango::GetWidth(const PRUnichar* aString, PRUint32 aLength,
- nscoord& aWidth, PRInt32 *aFontID,
- nsRenderingContextGTK *aContext)
+ nscoord& aWidth, PRInt32 *aFontID
+ CONTEXT_ARG_DEF)
{
- nsresult rv = NS_OK;
- PangoLayout *layout = pango_layout_new(mPangoContext);
-
- gchar *text = g_utf16_to_utf8(aString, aLength,
- NULL, NULL, NULL);
-
- if (!text) {
- aWidth = 0;
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
- DUMP_PRUNICHAR(aString, aLength)
-#endif
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
-
gint width, height;
-
- pango_layout_set_text(layout, text, strlen(text));
- FixupSpaceWidths(layout, text);
+ PangoLayout *layout = GetLayout(aString, aLength);
pango_layout_get_size(layout, &width, &height);
+ g_object_unref(layout);
- float f;
- f = mDeviceContext->DevUnitsToAppUnits();
+ float f = mDeviceContext->DevUnitsToAppUnits();
aWidth = NSToCoordRound(width * f / PANGO_SCALE);
- // printf("GetWidth %d\n", aWidth);
-
- loser:
- g_free(text);
- g_object_unref(layout);
-
- return rv;
+ return NS_OK;
}
nsresult
-nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
+nsFontMetricsPango::GetTextDimensions(const char* aString,
PRUint32 aLength,
- nsTextDimensions& aDimensions,
- PRInt32* aFontID,
- nsRenderingContextGTK *aContext)
+ nsTextDimensions& aDimensions
+ CONTEXT_ARG_DEF)
{
- nsresult rv = NS_OK;
-
- PangoLayout *layout = pango_layout_new(mPangoContext);
+ PangoLayout *layout = GetLayout(aString, aLength);
+ PangoLayoutLine *line = pango_layout_get_line(layout, 0);
- gchar *text = g_utf16_to_utf8(aString, aLength,
- NULL, NULL, NULL);
-
- if (!text) {
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::GetTextDimensions invalid unicode to follow");
- DUMP_PRUNICHAR(aString, aLength)
-#endif
- aDimensions.width = 0;
- aDimensions.ascent = 0;
- aDimensions.descent = 0;
-
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
-
+ PangoRectangle logical;
+ pango_layout_line_get_extents(line, NULL, &logical);
+ g_object_unref(layout);
- pango_layout_set_text(layout, text, strlen(text));
- FixupSpaceWidths(layout, text);
+ float P2T = mDeviceContext->DevUnitsToAppUnits();
- // Get the logical extents
- PangoLayoutLine *line;
- if (pango_layout_get_line_count(layout) != 1) {
- printf("Warning: more than one line!\n");
- }
- line = pango_layout_get_line(layout, 0);
+ aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(logical) * P2T / PANGO_SCALE);
+ aDimensions.descent = NSToCoordRound(PANGO_DESCENT(logical) * P2T / PANGO_SCALE);
+ aDimensions.width = NSToCoordRound(logical.width * P2T / PANGO_SCALE);
- PangoRectangle rect;
- pango_layout_line_get_extents(line, NULL, &rect);
+ return NS_OK;
+}
- float P2T;
- P2T = mDeviceContext->DevUnitsToAppUnits();
+nsresult
+nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
+ PRUint32 aLength,
+ nsTextDimensions& aDimensions,
+ PRInt32* aFontID
+ CONTEXT_ARG_DEF)
+{
+ PangoLayout *layout = GetLayout(aString, aLength);
+ PangoLayoutLine *line = pango_layout_get_line(layout, 0);
- aDimensions.width = NSToCoordRound(rect.width * P2T / PANGO_SCALE);
- aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) * P2T / PANGO_SCALE);
- aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) * P2T / PANGO_SCALE);
+ PangoRectangle logical;
+ pango_layout_line_get_extents(line, NULL, &logical);
+ g_object_unref(layout);
- // printf("GetTextDimensions %d %d %d\n", aDimensions.width,
- //aDimensions.ascent, aDimensions.descent);
+ float P2T = mDeviceContext->DevUnitsToAppUnits();
- loser:
- g_free(text);
- g_object_unref(layout);
+ aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(logical) * P2T / PANGO_SCALE);
+ aDimensions.descent = NSToCoordRound(PANGO_DESCENT(logical) * P2T / PANGO_SCALE);
+ aDimensions.width = NSToCoordRound(logical.width * P2T / PANGO_SCALE);
- return rv;
+ return NS_OK;
}
nsresult
@@ -595,13 +626,13 @@ nsFontMetricsPango::GetTextDimensions(co
nsTextDimensions& aDimensions,
PRInt32& aNumCharsFit,
nsTextDimensions& aLastWordDimensions,
- PRInt32* aFontID,
- nsRenderingContextGTK *aContext)
+ PRInt32* aFontID
+ CONTEXT_ARG_DEF)
{
return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks,
aNumBreaks, aDimensions, aNumCharsFit,
- aLastWordDimensions, aContext);
+ aLastWordDimensions CONTEXT_ARG_PASS);
}
@@ -614,8 +645,8 @@ nsFontMetricsPango::GetTextDimensions(co
nsTextDimensions& aDimensions,
PRInt32& aNumCharsFit,
nsTextDimensions& aLastWordDimensions,
- PRInt32* aFontID,
- nsRenderingContextGTK *aContext)
+ PRInt32* aFontID
+ CONTEXT_ARG_DEF)
{
nsresult rv = NS_OK;
PRInt32 curBreak = 0;
@@ -623,23 +654,15 @@ nsFontMetricsPango::GetTextDimensions(co
PRInt32 *utf8Breaks = new PRInt32[aNumBreaks];
- gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength,
- NULL, NULL, NULL);
+ gchar* text;
+ gint text_len;
+ utf16_to_utf8 (aString, aLength, text, text_len);
curChar = text;
- if (!text) {
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
- DUMP_PRUNICHAR(aString, (PRUint32)aLength)
-#endif
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
-
// Covert the utf16 break offsets to utf8 break offsets
for (PRInt32 curOffset=0; curOffset < aLength;
- curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
+ curOffset++, curChar = g_utf8_next_char(curChar)) {
if (aBreaks[curBreak] == curOffset) {
utf8Breaks[curBreak] = curChar - text;
curBreak++;
@@ -653,10 +676,10 @@ nsFontMetricsPango::GetTextDimensions(co
utf8Breaks[curBreak] = curChar - text;
#if 0
- if (strlen(text) != aLength) {
- printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text));
+ if (text_len != aLength) {
+ printf("Different lengths for utf16 %d and utf8 %d\n", aLength, text_len);
DUMP_PRUNICHAR(aString, aLength)
- DUMP_PRUNICHAR(text, strlen(text))
+ DUMP_PRUNICHAR(text, text_len)
for (PRInt32 i = 0; i < aNumBreaks; ++i) {
printf(" break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]);
}
@@ -666,9 +689,9 @@ nsFontMetricsPango::GetTextDimensions(co
// We'll use curBreak to indicate which of the breaks end up being
// used for the break point for this line.
curBreak = 0;
- rv = GetTextDimensionsInternal(text, strlen(text), aAvailWidth, utf8Breaks,
+ rv = GetTextDimensionsInternal(text, text_len, aAvailWidth, utf8Breaks,
aNumBreaks, aDimensions, aNumCharsFit,
- aLastWordDimensions, aContext);
+ aLastWordDimensions CONTEXT_ARG_PASS);
// Figure out which of the breaks we ended up using to convert
// back to utf16 - start from the end.
@@ -681,200 +704,365 @@ nsFontMetricsPango::GetTextDimensions(co
}
}
- loser:
- if (text)
- g_free(text);
+ g_free(text);
delete[] utf8Breaks;
return rv;
}
-nsresult
-nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
- nscoord aX, nscoord aY,
- const nscoord* aSpacing,
- nsRenderingContextGTK *aContext,
- nsDrawingSurfaceGTK *aSurface)
+#ifdef PSPANGO
+
+typedef struct _nsPSPangoRenderer nsPSPangoRenderer;
+typedef struct _nsPSPangoRendererClass nsPSPangoRendererClass;
+
+struct _nsPSPangoRenderer
{
- PangoLayout *layout = pango_layout_new(mPangoContext);
+ PangoRenderer parent_instance;
+ nsRenderingContextPS *psContext;
+ nsFontMetricsPSPango *psPangoFontMetrics;
+ float zoom;
+};
- pango_layout_set_text(layout, aString, aLength);
- FixupSpaceWidths(layout, aString);
+struct _nsPSPangoRendererClass
+{
+ PangoRendererClass parent_class;
+};
- int x = aX;
- int y = aY;
+#define _PS_TYPE_PANGO_RENDERER (_ps_pango_renderer_get_type())
+#define _PS_PANGO_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRenderer))
+#define _PS_IS_PANGO_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), _PS_TYPE_PANGO_RENDERER))
+#define _PS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
+#define _PS_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), _PS_TYPE_PANGO_RENDERER))
+#define _PS_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
- aContext->GetTranMatrix()->TransformCoord(&x, &y);
+G_DEFINE_TYPE (_nsPSPangoRenderer, _ps_pango_renderer, PANGO_TYPE_RENDERER)
- PangoLayoutLine *line;
- if (pango_layout_get_line_count(layout) != 1) {
- printf("Warning: more than one line!\n");
- }
- line = pango_layout_get_line(layout, 0);
+static PangoRenderer *
+get_renderer (void)
+{
+ static PangoRenderer *renderer = NULL;
- aContext->UpdateGC();
- GdkGC *gc = aContext->GetGC();
+ if (!renderer)
+ renderer = (PangoRenderer *) g_object_new (_PS_TYPE_PANGO_RENDERER, NULL);
- if (aSpacing && *aSpacing) {
- DrawStringSlowly(aString, NULL, aLength, aSurface->GetDrawable(),
- gc, x, y, line, aSpacing);
- }
- else {
- gdk_draw_layout_line(aSurface->GetDrawable(), gc,
- x, y,
- line);
- }
+ return renderer;
+}
- g_object_unref(gc);
- g_object_unref(layout);
+static void
+_ps_pango_renderer_draw_glyphs (PangoRenderer *renderer,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ int x,
+ int y);
- // printf("DrawString (char *)\n");
+static void
+_ps_pango_renderer_class_init (nsPSPangoRendererClass *klass)
+{
+ PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
+
+ renderer_class->draw_glyphs = _ps_pango_renderer_draw_glyphs;
+}
- return NS_OK;
+static void
+_ps_pango_renderer_init (nsPSPangoRenderer *renderer)
+{
+}
+
+class nsPangoType1Generator : public nsPSFontGenerator {
+public:
+ nsPangoType1Generator();
+ ~nsPangoType1Generator();
+ nsresult Init(PangoFont *aFont);
+ void GeneratePSFont(FILE* aFile);
+
+protected:
+ PangoFont *mFont;
+};
+
+nsPangoType1Generator::nsPangoType1Generator()
+{
}
nsresult
-nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
- nscoord aX, nscoord aY,
- PRInt32 aFontID,
- const nscoord* aSpacing,
- nsRenderingContextGTK *aContext,
- nsDrawingSurfaceGTK *aSurface)
+nsPangoType1Generator::Init(PangoFont *aFont)
+ {
+ NS_ENSURE_TRUE(aFont, NS_ERROR_FAILURE);
+ mFont = aFont;
+ g_object_ref (mFont);
+ return NS_OK;
+}
+
+nsPangoType1Generator::~nsPangoType1Generator()
{
- nsresult rv = NS_OK;
- int x = aX;
- int y = aY;
+ g_object_unref (mFont);
+ mFont = nsnull;
+}
- aContext->UpdateGC();
- GdkGC *gc = aContext->GetGC();
+void nsPangoType1Generator::GeneratePSFont(FILE* aFile)
+{
+ FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) mFont);
- PangoLayout *layout = pango_layout_new(mPangoContext);
+ if (face == nsnull)
+ return;
- gchar *text = g_utf16_to_utf8(aString, aLength,
- NULL, NULL, NULL);
+ int wmode = 0;
+ if (mGlyphSubset->Count())
+ FT2SubsetToType1FontSet(face, mGlyphSubset, wmode, aFile);
- if (!text) {
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::DrawString invalid unicode to follow");
- DUMP_PRUNICHAR(aString, aLength)
-#endif
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
+ pango_fc_font_unlock_face ((PangoFcFont *) mFont);
+}
- pango_layout_set_text(layout, text, strlen(text));
- FixupSpaceWidths(layout, text);
+typedef struct
+{
+ nsCString *FontNameBase;
+ nsCStringKey *key;
+ int font_size;
+} PSPangoFontData;
- aContext->GetTranMatrix()->TransformCoord(&x, &y);
+static void
+ps_pango_font_data_destroy (PSPangoFontData *data)
+{
+ delete data->key;
+ delete data->FontNameBase;
+ g_free (data);
+}
- PangoLayoutLine *line;
- if (pango_layout_get_line_count(layout) != 1) {
- printf("Warning: more than one line!\n");
- }
- line = pango_layout_get_line(layout, 0);
+static void
+_ps_pango_renderer_draw_glyphs (PangoRenderer *renderer,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ int x,
+ int y)
+{
+ if (!glyphs->num_glyphs)
+ return;
- if (aSpacing && *aSpacing) {
- DrawStringSlowly(text, aString, aLength, aSurface->GetDrawable(),
- gc, x, y, line, aSpacing);
- }
- else {
- gdk_draw_layout_line(aSurface->GetDrawable(), gc,
- x, y,
- line);
- }
+ static GQuark data_quark = 0;
+ if (!data_quark)
+ data_quark = g_quark_from_static_string ("ps-pango-font-data");
- loser:
+ PSPangoFontData *data;
+ if (!(data = (PSPangoFontData *) g_object_get_qdata (G_OBJECT (font), data_quark)))
+ {
+ data = g_new (PSPangoFontData, 1);
- g_free(text);
- g_object_unref(gc);
- g_object_unref(layout);
+ FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) font);
+ if (face == nsnull)
+ return;
+ int wmode = 0;
+ data->FontNameBase = new nsCString ();
+ if (NS_FAILED(FT2ToType1FontName(face, wmode, *data->FontNameBase))) {
+ g_free (data);
+ pango_fc_font_unlock_face ((PangoFcFont *) font);
+ return;
+ }
+ pango_fc_font_unlock_face ((PangoFcFont *) font);
- // printf("DrawString\n");
+ PangoFontDescription *desc = pango_font_describe (font);
+ data->font_size = pango_font_description_get_size (desc);
+ pango_font_description_free (desc);
+
+ data->key = new nsCStringKey (*data->FontNameBase);
+
+ g_object_set_qdata_full (G_OBJECT (font), data_quark, data, (GDestroyNotify) ps_pango_font_data_destroy);
+ }
+
+ nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
+ nsRenderingContextPS *aContext = ps_renderer->psContext;
+ nsFontMetricsPSPango *metrics = ps_renderer->psPangoFontMetrics;
+ nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, metrics->GetDeviceContext());
+ nsPostScriptObj* psObj = aContext->GetPostScriptObj();
+ nsHashtable *psFGList = dc->GetPSFontGeneratorList();
+ g_return_if_fail (psFGList);
+ nsPSFontGenerator* psFontGen = (nsPSFontGenerator*) psFGList->Get(data->key);
+ if (!psFontGen) {
+ nsresult rv;
+ psFontGen = new nsPangoType1Generator;
+ g_return_if_fail (psFontGen);
+ rv = ((nsPangoType1Generator*)psFontGen)->Init(font);
+ if (NS_FAILED(rv)) {
+ delete psFontGen;
+ return;
+ }
+ psFGList->Put(data->key, (void *) psFontGen);
+ }
+ nscoord font_size = NSToCoordRound (ps_renderer->zoom * data->font_size / PANGO_SCALE);
+
+ g_return_if_fail (aContext);
+ g_return_if_fail (psObj);
+
+ nscoord aX = NSToCoordRound(ps_renderer->zoom * x / PANGO_SCALE);
+ nscoord aY = NSToCoordRound(ps_renderer->zoom * y / PANGO_SCALE);
+ psObj->moveto(aX, aY);
+
+ PRInt32 currSubFont, prevSubFont = -1;
+ PRUint32 i;
+ PangoGlyphString gl;
+
+ gl.glyphs = glyphs->glyphs;
+ gl.num_glyphs = 0;
+ currSubFont = prevSubFont;
+ for (i = 0; i < glyphs->num_glyphs; ++i) {
+ PangoGlyph glyph = glyphs->glyphs[i].glyph;
+
+ if (glyph != PANGO_GLYPH_EMPTY)
+ currSubFont = psFontGen->AddToGlyphSubset(glyph > 0x0fffffff ? 0 : glyph);
+
+ if (prevSubFont != currSubFont) {
+ if (prevSubFont != -1)
+ psObj->show(&gl, ps_renderer->zoom, psFontGen, prevSubFont);
+
+ psObj->setfont(*data->FontNameBase, (PRUint32) font_size, currSubFont);
+ prevSubFont = currSubFont;
+ gl.glyphs = glyphs->glyphs + i;
+ gl.num_glyphs = 0;
+ }
- return rv;
+ gl.num_glyphs++;
+ }
+
+ if (prevSubFont != -1)
+ psObj->show(&gl, ps_renderer->zoom, psFontGen, prevSubFont);
}
+#endif
+
+static void
+draw_layout_line (int x, int y,
+ PangoLayoutLine *line,
+ nsFontMetricsPango *fm
+ CONTEXT_AND_SURFACE_ARG_DEF)
+{
+#ifdef PSPANGO
+ PangoRenderer *renderer = get_renderer ();
+ nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
+ ps_renderer->psContext = aContext;
+ ps_renderer->psPangoFontMetrics = fm;
+ nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, fm->GetDeviceContext());
+ ps_renderer->zoom = dc->DevUnitsToAppUnits();
+
+ pango_renderer_draw_layout_line (renderer, line,
+ NSToCoordRound (x * PANGO_SCALE / ps_renderer->zoom),
+ NSToCoordRound (y * PANGO_SCALE / ps_renderer->zoom));
+#else
+ aContext->UpdateGC();
+ GdkGC *gc = aContext->GetGC();
+ gdk_draw_layout_line(aSurface->GetDrawable(), gc, x, y, line);
+ g_object_unref(gc);
+#endif
+}
+
-#ifdef MOZ_MATHML
nsresult
-nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
- nsBoundingMetrics &aBoundingMetrics,
- nsRenderingContextGTK *aContext)
+nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
+ nscoord aX, nscoord aY,
+ const nscoord* aSpacing
+ CONTEXT_AND_SURFACE_ARG_DEF)
{
- printf("GetBoundingMetrics (char *)\n");
- return NS_ERROR_FAILURE;
+ int x = aX;
+ int y = aY;
+
+ aContext->GetTranMatrix()->TransformCoord(&x, &y);
+
+ PangoLayout *layout = GetLayout(aString, aLength);
+ PangoLayoutLine *line = pango_layout_get_line(layout, 0);
+
+ ApplySpacing(aString, aLength, line, aSpacing);
+ draw_layout_line(x, y, line, this CONTEXT_AND_SURFACE_ARG_PASS);
+
+ g_object_unref(layout);
+
+ return NS_OK;
}
nsresult
-nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
- PRUint32 aLength,
- nsBoundingMetrics &aBoundingMetrics,
- PRInt32 *aFontID,
- nsRenderingContextGTK *aContext)
+nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
+ nscoord aX, nscoord aY,
+ PRInt32 aFontID,
+ const nscoord* aSpacing
+ CONTEXT_AND_SURFACE_ARG_DEF)
{
- nsresult rv = NS_OK;
- PangoLayout *layout = pango_layout_new(mPangoContext);
+ int x = aX;
+ int y = aY;
- gchar *text = g_utf16_to_utf8(aString, aLength,
- NULL, NULL, NULL);
+ aContext->GetTranMatrix()->TransformCoord(&x, &y);
- if (!text) {
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::GetBoundingMetrics invalid unicode to follow");
- DUMP_PRUNICHAR(aString, aLength)
-#endif
- aBoundingMetrics.Clear();
+ PangoLayout *layout = GetLayout(aString, aLength);
+ PangoLayoutLine *line = pango_layout_get_line(layout, 0);
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
+ ApplySpacing(aString, aLength, line, aSpacing);
+ draw_layout_line(x, y, line, this CONTEXT_AND_SURFACE_ARG_PASS);
- pango_layout_set_text(layout, text, -1);
- FixupSpaceWidths(layout, text);
+ g_object_unref(layout);
+
+ return NS_OK;
+}
- PangoLayoutLine *line;
- if (pango_layout_get_line_count(layout) != 1) {
- printf("Warning: more than one line!\n");
- }
- line = pango_layout_get_line(layout, 0);
+
+#ifdef MOZ_MATHML
+void
+nsFontMetricsPango::GetBoundingMetricsInternal(PangoLayout *aLayout,
+ nsBoundingMetrics &aBoundingMetrics
+ CONTEXT_ARG_DEF)
+{
+ PangoLayoutLine *line = pango_layout_get_line(aLayout, 0);
// Get the ink and logical extents
PangoRectangle ink, logical;
pango_layout_line_get_extents(line, &ink, &logical);
- float P2T;
- P2T = mDeviceContext->DevUnitsToAppUnits();
+ float P2T = mDeviceContext->DevUnitsToAppUnits();
aBoundingMetrics.leftBearing = NSToCoordRound(PANGO_LBEARING(ink) * P2T / PANGO_SCALE);
aBoundingMetrics.rightBearing = NSToCoordRound(PANGO_RBEARING(ink) * P2T / PANGO_SCALE);
aBoundingMetrics.ascent = NSToCoordRound(PANGO_ASCENT(ink) * P2T / PANGO_SCALE);
aBoundingMetrics.descent = NSToCoordRound(PANGO_DESCENT(ink) * P2T / PANGO_SCALE);
aBoundingMetrics.width = NSToCoordRound(logical.width * P2T / PANGO_SCALE);
+}
- loser:
- g_free(text);
+nsresult
+nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
+ nsBoundingMetrics &aBoundingMetrics
+ CONTEXT_ARG_DEF)
+{
+ PangoLayout *layout = GetLayout(aString, aLength);
+ GetBoundingMetricsInternal (layout, aBoundingMetrics CONTEXT_ARG_PASS);
g_object_unref(layout);
- return rv;
+ return NS_OK;
+}
+
+nsresult
+nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
+ PRUint32 aLength,
+ nsBoundingMetrics &aBoundingMetrics,
+ PRInt32 *aFontID
+ CONTEXT_ARG_DEF)
+{
+ PangoLayout *layout = GetLayout(aString, aLength);
+ GetBoundingMetricsInternal (layout, aBoundingMetrics CONTEXT_ARG_PASS);
+ g_object_unref(layout);
+
+ return NS_OK;
}
#endif /* MOZ_MATHML */
+#ifndef PSPANGO
GdkFont*
nsFontMetricsPango::GetCurrentGDKFont(void)
{
return nsnull;
}
+#endif
nsresult
nsFontMetricsPango::SetRightToLeftText(PRBool aIsRTL)
{
if (aIsRTL) {
if (!mRTLPangoContext) {
- mRTLPangoContext = gdk_pango_context_get();
+ mRTLPangoContext = get_context();
pango_context_set_base_dir(mRTLPangoContext, PANGO_DIRECTION_RTL);
-
- gdk_pango_context_set_colormap(mRTLPangoContext, gdk_rgb_get_cmap());
pango_context_set_language(mRTLPangoContext, GetPangoLanguage(mLangGroup));
pango_context_set_font_description(mRTLPangoContext, mPangoFontDesc);
}
@@ -899,34 +1087,18 @@ nsFontMetricsPango::GetClusterInfo(const
PRUint32 aLength,
PRUint8 *aClusterStarts)
{
- nsresult rv = NS_OK;
PangoLogAttr *attrs = NULL;
gint n_attrs = 0;
- PangoLayout *layout = pango_layout_new(mPangoContext);
-
- // Convert the incoming UTF-16 to UTF-8
- gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
- if (!text) {
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
- DUMP_PRUNICHAR(aText, aLength)
-#endif
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
-
- // Set up the pango layout
- pango_layout_set_text(layout, text, strlen(text));
- FixupSpaceWidths(layout, text);
+ PangoLayout *layout = GetLayout(aText, aLength);
+ pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
+ g_object_unref(layout);
// Convert back to UTF-16 while filling in the cluster info
// structure.
- pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
-
for (PRUint32 pos = 0; pos < aLength; pos++) {
if (IS_HIGH_SURROGATE(aText[pos])) {
- aClusterStarts[pos] = 1;
+ aClusterStarts[pos] = 1;//FIXME: shouldn't this be zero?! --be
pos++;
}
else {
@@ -934,56 +1106,34 @@ nsFontMetricsPango::GetClusterInfo(const
}
}
- loser:
- if (attrs)
- g_free(attrs);
- if (text)
- g_free(text);
- if (layout)
- g_object_unref(layout);
+ g_free(attrs);
- return rv;
+ return NS_OK;
}
PRInt32
-nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength,
- nsPoint aPt)
+nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength, nsPoint aPt)
{
int trailing = 0;
int inx = 0;
- const gchar *curChar;
PRInt32 retval = 0;
float f = mDeviceContext->AppUnitsToDevUnits();
- PangoLayout *layout = pango_layout_new(mPangoContext);
PRUint32 localX = (PRUint32)(aPt.x * PANGO_SCALE * f);
PRUint32 localY = (PRUint32)(aPt.y * PANGO_SCALE * f);
- // Convert the incoming UTF-16 to UTF-8
- gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
-
- if (!text) {
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
- DUMP_PRUNICHAR(aText, aLength)
-#endif
- retval = -1;
- goto loser;
- }
-
- // Set up the pango layout
- pango_layout_set_text(layout, text, strlen(text));
- FixupSpaceWidths(layout, text);
+ PangoLayout *layout = GetLayout(aText, aLength);
pango_layout_xy_to_index(layout, localX, localY,
&inx, &trailing);
// Convert the index back to the utf-16 index
- curChar = text;
+ const gchar *text = pango_layout_get_text (layout);
+ const gchar *curChar = text;
for (PRUint32 curOffset=0; curOffset < aLength;
- curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
+ curOffset++, curChar = g_utf8_next_char(curChar)) {
// Check for a match before checking for a surrogate pair
if (curChar - text == inx) {
@@ -1006,13 +1156,9 @@ nsFontMetricsPango::GetPosition(const PR
trailing--;
}
- loser:
- if (text)
- g_free(text);
- if (layout)
- g_object_unref(layout);
+ g_object_unref(layout);
- return retval;
+ return retval;
}
nsresult
@@ -1022,28 +1168,21 @@ nsFontMetricsPango::GetRangeWidth(const
PRUint32 aEnd,
PRUint32 &aWidth)
{
- nsresult rv = NS_OK;
PRUint32 utf8Start = 0;
PRUint32 utf8End = 0;
aWidth = 0;
// Convert the incoming UTF-16 to UTF-8
- gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
- gchar *curChar = text;
- if (!text) {
-#ifdef DEBUG
- NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
- DUMP_PRUNICHAR(aText, aLength)
-#endif
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
+ gchar* text;
+ gint text_len;
+ utf16_to_utf8 (aText, aLength, text, text_len);
+ gchar *curChar = text;
// Convert the utf16 offsets into utf8 offsets
for (PRUint32 curOffset = 0; curOffset < aLength;
- curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
+ curOffset++, curChar = g_utf8_next_char(curChar)) {
if (curOffset == aStart)
utf8Start = curChar - text;
@@ -1057,15 +1196,13 @@ nsFontMetricsPango::GetRangeWidth(const
// Special case where the end index is the same as the length
if (aLength == aEnd)
- utf8End = strlen(text);
+ utf8End = text_len;
- rv = GetRangeWidth(text, strlen(text), utf8Start, utf8End, aWidth);
+ GetRangeWidth(text, text_len, utf8Start, utf8End, aWidth);
- loser:
- if (text)
- g_free(text);
+ g_free(text);
- return rv;
+ return NS_OK;
}
nsresult
@@ -1075,43 +1212,26 @@ nsFontMetricsPango::GetRangeWidth(const
PRUint32 aEnd,
PRUint32 &aWidth)
{
- nsresult rv = NS_OK;
int *ranges = NULL;
int n_ranges = 0;
float f;
aWidth = 0;
- PangoLayout *layout = pango_layout_new(mPangoContext);
-
- if (!aText) {
- rv = NS_ERROR_FAILURE;
- goto loser;
- }
-
- pango_layout_set_text(layout, aText, aLength);
- FixupSpaceWidths(layout, aText);
-
- PangoLayoutLine *line;
- if (pango_layout_get_line_count(layout) != 1) {
- printf("Warning: more than one line!\n");
- }
- line = pango_layout_get_line(layout, 0);
+ PangoLayout *layout = GetLayout(aText, aLength);
+ PangoLayoutLine *line = pango_layout_get_line(layout, 0);
pango_layout_line_get_x_ranges(line, aStart, aEnd, &ranges, &n_ranges);
aWidth = (ranges[((n_ranges - 1) * 2) + 1] - ranges[0]);
f = mDeviceContext-> DevUnitsToAppUnits();
- aWidth = nscoord(aWidth * f / PANGO_SCALE);
+ aWidth = NSToCoordRound(aWidth * f / PANGO_SCALE);
- loser:
- if (ranges)
- g_free(ranges);
- if (layout)
- g_object_unref(layout);
+ g_free(ranges);
+ g_object_unref(layout);
- return rv;
+ return NS_OK;
}
/* static */
@@ -1134,7 +1254,7 @@ nsFontMetricsPango::FamilyExists(nsIDevi
NS_ConvertUTF16toUTF8 name(aName);
nsresult rv = NS_ERROR_FAILURE;
- PangoContext *context = gdk_pango_context_get();
+ PangoContext *context = get_context();
PangoFontFamily **familyList;
int n;
@@ -1233,16 +1353,13 @@ nsFontMetricsPango::RealizeFont(void)
// Now that we have the font description set up, create the
// context.
- mLTRPangoContext = gdk_pango_context_get();
+ mLTRPangoContext = get_context();
mPangoContext = mLTRPangoContext;
// Make sure to set the base direction to LTR - if layout needs to
// render RTL text it will use ::SetRightToLeftText()
pango_context_set_base_dir(mPangoContext, PANGO_DIRECTION_LTR);
- // Set the color map so we can draw later.
- gdk_pango_context_set_colormap(mPangoContext, gdk_rgb_get_cmap());
-
// Set the pango language now that we have a context
pango_context_set_language(mPangoContext, GetPangoLanguage(mLangGroup));
@@ -1280,79 +1397,268 @@ nsFontMetricsPango::EnumFontCallback(con
* This is only used when there's per-character spacing happening.
* Well, really it can be either line or character spacing but it's
* just turtles all the way down!
+ *
+ * To do it correctly (ligatures, etc) we need machinery that is private
+ * in Pango. IMPORT IT:
+ */
+
+#define _PangoGlyphItemIter _nsFontMetricsPangoGlyphItemIter
+#define PangoGlyphItemIter nsFontMetricsPangoGlyphItemIter
+
+#define LTR(glyph_item) (((glyph_item)->item->analysis.level % 2) == 0)
+
+/* Structure holding state when we're iterating over a GlyphItem.
+ * start_index/cluster_end (and range_start/range_end in
+ * apply_attrs()) are offsets into the text, so note the difference
+ * of glyph_item->item->offset between them and clusters in the
+ * log_clusters[] array.
*/
+typedef struct _PangoGlyphItemIter PangoGlyphItemIter;
+
+struct _PangoGlyphItemIter
+{
+ PangoGlyphItem *glyph_item;
+ const gchar *text;
+
+ int start_glyph;
+ int start_index;
+ int start_char;
+
+ int end_glyph;
+ int end_index;
+ int end_char;
+};
+
+/**
+ * _pango_glyph_item_iter_next_cluster:
+ * @iter: a #PangoGlyphItemIter
+ *
+ * Advances the iterator to the next cluster in the glyph item.
+ *
+ * Return value: %TRUE if the iterator was advanced, %FALSE if we were already on the
+ * last cluster.
+ **/
+static gboolean
+_pango_glyph_item_iter_next_cluster (PangoGlyphItemIter *iter)
+{
+ int glyph_index = iter->end_glyph;
+ PangoGlyphString *glyphs = iter->glyph_item->glyphs;
+ PangoItem *item = iter->glyph_item->item;
+
+ if (LTR (iter->glyph_item))
+ {
+ if (glyph_index == glyphs->num_glyphs)
+ return FALSE;
+ }
+ else
+ {
+ if (glyph_index < 0)
+ return FALSE;
+ }
+
+ iter->start_glyph = iter->end_glyph;
+ iter->start_index = iter->end_index;
+ iter->start_char = iter->end_char;
+
+ if (LTR (iter->glyph_item))
+ {
+ while (TRUE)
+ {
+ glyph_index++;
+
+ if (glyph_index == glyphs->num_glyphs)
+ {
+ iter->end_index = item->offset + item->length;
+ iter->end_char = item->num_chars;
+ break;
+ }
+
+ if (item->offset + glyphs->log_clusters[glyph_index] != iter->start_index)
+ {
+ iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
+ iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
+ iter->end_index - iter->start_index);
+ break;
+ }
+ }
+ }
+ else /* RTL */
+ {
+ while (TRUE)
+ {
+ glyph_index--;
+
+ if (glyph_index < 0)
+ {
+ iter->end_index = item->offset + item->length;
+ iter->end_char = item->num_chars;
+ break;
+ }
+
+ if (item->offset + glyphs->log_clusters[glyph_index] != iter->start_index)
+ {
+ iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
+ iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
+ iter->end_index - iter->start_index);
+ break;
+ }
+ }
+ }
+
+ iter->end_glyph = glyph_index;
+ return TRUE;
+}
+
+/**
+ * _pango_glyph_item_iter_init_start:
+ * @iter: pointer to a #PangoGlyphItemIter structure
+ * @glyph_item: the glyph item that the iter points into
+ * @text: text corresponding to the glyph item
+ *
+ * Initializes a #PangoGlyphItemIter structure to point to the
+ * first cluster in a glyph item.
+ *
+ * Return value: %FALSE if there are no clusters in the glyph item;
+ * in this case, the state of the iter is undefined.
+ **/
+static gboolean
+_pango_glyph_item_iter_init_start (PangoGlyphItemIter *iter,
+ PangoGlyphItem *glyph_item,
+ const char *text)
+{
+ iter->glyph_item = glyph_item;
+ iter->text = text;
+
+ if (LTR (glyph_item))
+ iter->end_glyph = 0;
+ else
+ iter->end_glyph = glyph_item->glyphs->num_glyphs - 1;
+
+ iter->end_index = glyph_item->item->offset;
+ iter->end_char = 0;
+
+ /* Advance onto the first cluster of the glyph item */
+ return _pango_glyph_item_iter_next_cluster (iter);
+}
+
void
-nsFontMetricsPango::DrawStringSlowly(const gchar *aText,
- const PRUnichar *aOrigString,
- PRUint32 aLength,
- GdkDrawable *aDrawable,
- GdkGC *aGC, gint aX, gint aY,
- PangoLayoutLine *aLine,
- const nscoord *aSpacing)
-{
- float app2dev;
- app2dev = mDeviceContext->AppUnitsToDevUnits();
- gint offset = 0;
+nsFontMetricsPango::ApplySpacing(const gchar *aText,
+ PRUint32 aLength,
+ PangoLayoutLine *aLine,
+ const nscoord *aSpacing)
+{
+ if (!(aSpacing && *aSpacing))
+ return;
+
+ float app2dev = mDeviceContext->AppUnitsToDevUnits();
/*
* We walk the list of glyphs returned in each layout run,
* matching up the glyphs with the characters in the source text.
* We use the aSpacing argument to figure out where to place those
- * glyphs. It's important to note that since the string we're
- * working with is in UTF-8 while the spacing argument assumes
- * that offset will be part of the UTF-16 string. Logical
- * attributes in pango are in byte offsets in the UTF-8 string, so
- * we need to store the offsets based on the UTF-8 string.
+ * glyphs.
*/
- nscoord *utf8spacing = new nscoord[strlen(aText)];
+ for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
+ tmpList = tmpList->next) {
+ PangoGlyphItem *glyph_item = (PangoGlyphItem *)tmpList->data;
+ PangoGlyphItemIter iter;
+ gboolean have_cluster;
+ PangoGlyphInfo *glyphs = glyph_item->glyphs->glyphs;
+ int residualWidth = 0;
+
+ for (have_cluster = _pango_glyph_item_iter_init_start (&iter, glyph_item, aText);
+ have_cluster;
+ have_cluster = _pango_glyph_item_iter_next_cluster (&iter))
+ {
+ int clusterOldWidth = 0;
+ int clusterNewWidth = 0;
+ int dir = iter.start_glyph < iter.end_glyph ? +1 : -1;
+ gboolean has_zero_width = FALSE;
+
+ for (const char *p = iter.text + iter.start_index;
+ p < iter.text + iter.end_index;
+ p = g_utf8_next_char (p))
+ clusterNewWidth += aSpacing[p - iter.text];
+
+ clusterNewWidth = (gint)(clusterNewWidth * app2dev * PANGO_SCALE);
+
+ for (gint i = iter.start_glyph; i != iter.end_glyph; i += dir) {
+ if (!glyphs[i].geometry.width)
+ has_zero_width = TRUE;
+ clusterOldWidth += glyphs[i].geometry.width;
+ }
+
+ /* if a zero-width glyph exists, don't touch the glyph widths.
+ * required for combining marks. ff thinks they have a width.
+ * instead, we charge the difference to the next space glyph. */
+ if (has_zero_width) {
+ residualWidth += clusterNewWidth - clusterOldWidth;
+ continue;
+ }
- if (aOrigString) {
- const gchar *curChar = aText;
- bzero(utf8spacing, sizeof(nscoord) * strlen(aText));
-
- // Covert the utf16 spacing offsets to utf8 spacing offsets
- for (PRUint32 curOffset=0; curOffset < aLength;
- curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
- utf8spacing[curChar - aText] = aSpacing[curOffset];
+ /* If a space glyph is found, charge it whatever residual we
+ * have accumulated so far. */
+ if (iter.end_index - iter.start_index == 1 &&
+ *(iter.text + iter.start_index) == ' ') {
+ clusterNewWidth += residualWidth;
+ residualWidth = 0;
+ }
+
+#ifndef PSPANGO
+ /* do some hinting for display */
+
+ if (clusterOldWidth % PANGO_SCALE == 0 && clusterNewWidth % PANGO_SCALE != 0) {
+ int tmp = clusterNewWidth;
+ clusterNewWidth = PANGO_PIXELS (clusterNewWidth) * PANGO_SCALE;
+ residualWidth += tmp - clusterNewWidth;
+ }
+#endif
- if (IS_HIGH_SURROGATE(aOrigString[curOffset]))
- curOffset++;
+ /* find the first non-zero-width glyph and adjust its width */
+ for (gint i = iter.start_glyph; i != iter.end_glyph; i += dir)
+ if (glyphs[i].geometry.width) {
+ glyphs[i].geometry.width += clusterNewWidth - clusterOldWidth;
+ break;
+ }
}
}
- else {
- memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength));
- }
+}
- gint curRun = 0;
+void
+nsFontMetricsPango::ApplySpacing(const PRUnichar *aText,
+ PRUint32 aLength,
+ PangoLayoutLine *aLine,
+ const nscoord *aSpacing)
+{
+ if (!(aSpacing && *aSpacing))
+ return;
- for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
- tmpList = tmpList->next, curRun++) {
- PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data;
- gint tmpOffset = 0;
+ const char *utf8Text = pango_layout_get_text (aLine->layout);
+ int utf8Text_len = aLine->start_index + aLine->length;
- /* printf(" Rendering run %d: \"%s\"\n", curRun,
- &aText[layoutRun->item->offset]); */
+ /* Since the string we're
+ * working with is in UTF-8 while the spacing argument assumes
+ * that offset will be part of the UTF-16 string. Logical
+ * attributes in pango are in byte offsets in the UTF-8 string, so
+ * we need to store the offsets based on the UTF-8 string.
+ */
+ nscoord *utf8spacing = g_new0 (nscoord, utf8Text_len);
- for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) {
- /* printf("glyph %d offset %d orig width %d new width %d\n", i,
- * layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset,
- * layoutRun->glyphs->glyphs[i].geometry.width,
- * (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] * app2dev * PANGO_SCALE));
- */
- gint thisOffset = (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset]
- * app2dev * PANGO_SCALE);
- layoutRun->glyphs->glyphs[i].geometry.width = thisOffset;
- tmpOffset += thisOffset;
- }
+ const gchar *curChar = utf8Text + aLine->start_index;
- /* printf(" rendering at X coord %d\n", aX + offset); */
- offset += tmpOffset;
+ // Covert the utf16 spacing offsets to utf8 spacing offsets
+ for (PRUint32 curOffset=0; curOffset < aLength;
+ curOffset++, curChar = g_utf8_next_char(curChar)) {
+ utf8spacing[curChar - utf8Text] = aSpacing[curOffset];
+
+ if (IS_HIGH_SURROGATE(aText[curOffset]))
+ curOffset++;
}
- gdk_draw_layout_line(aDrawable, aGC, aX, aY, aLine);
+ ApplySpacing (utf8Text, utf8Text_len, aLine, utf8spacing);
- delete[] utf8spacing;
+ g_free (utf8spacing);
}
nsresult
@@ -1363,8 +1669,8 @@ nsFontMetricsPango::GetTextDimensionsInt
PRInt32 aNumBreaks,
nsTextDimensions& aDimensions,
PRInt32& aNumCharsFit,
- nsTextDimensions& aLastWordDimensions,
- nsRenderingContextGTK *aContext)
+ nsTextDimensions& aLastWordDimensions
+ CONTEXT_ARG_DEF)
{
NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
@@ -1410,7 +1716,7 @@ nsFontMetricsPango::GetTextDimensionsInt
// All the characters should fit
numChars = aLength - start;
breakIndex = aNumBreaks - 1;
- }
+ }
else {
breakIndex = prevBreakState_BreakIndex;
while (((breakIndex + 1) < aNumBreaks) &&
@@ -1431,7 +1737,7 @@ nsFontMetricsPango::GetTextDimensionsInt
if ((1 == numChars) && (aString[start] == ' '))
GetSpaceWidth(twWidth);
else if (numChars > 0)
- GetWidth(&aString[start], numChars, twWidth, aContext);
+ GetWidth(&aString[start], numChars, twWidth CONTEXT_ARG_PASS);
// See if the text fits
PRBool textFits = (twWidth + width) <= aAvailWidth;
@@ -1481,8 +1787,7 @@ nsFontMetricsPango::GetTextDimensionsInt
if ((1 == numChars) && (aString[start] == ' '))
GetSpaceWidth(twWidth);
else if (numChars > 0)
- GetWidth(&aString[start], numChars, twWidth,
- aContext);
+ GetWidth(&aString[start], numChars, twWidth CONTEXT_ARG_PASS);
width -= twWidth;
aNumCharsFit = start;
breakIndex--;
@@ -1504,9 +1809,16 @@ nsFontMetricsPango::GetTextDimensionsInt
}
void
-nsFontMetricsPango::FixupSpaceWidths (PangoLayout *aLayout,
- const char *aString)
+nsFontMetricsPango::FixupSpaceWidths (PangoLayout *aLayout)
{
+ if (!mPangoSpaceWidth)
+ return;
+
+ const char *aString = pango_layout_get_text (aLayout);
+
+ if (pango_layout_get_line_count(aLayout) != 1) {
+ printf("Warning: more than one line!\n");
+ }
PangoLayoutLine *line = pango_layout_get_line(aLayout, 0);
gint curRun = 0;
@@ -1523,6 +1835,107 @@ nsFontMetricsPango::FixupSpaceWidths (Pa
}
}
+PangoLayout*
+nsFontMetricsPango::GetLayout (const PRUnichar* aText,
+ PRUint32 aLength)
+{
+ gchar* text;
+ gint length;
+ utf16_to_utf8 (aText, aLength, text, length);
+
+ PangoLayout *layout = pango_layout_new(mPangoContext);
+ pango_layout_set_text (layout, text, length);
+ FixupSpaceWidths (layout);
+
+ g_free ((gpointer) text);
+
+ return layout;
+}
+
+PangoLayout*
+nsFontMetricsPango::GetLayout (const gchar* aText,
+ PRInt32 aLength)
+{
+ gboolean has_nul = FALSE;
+ int i;
+
+ for (i = 0; i < aLength; i++)
+ if (!aText[i]) {
+ has_nul = TRUE;
+ break;
+ }
+
+ if (has_nul) {
+ /* Pango doesn't correctly handle nuls. We convert them to 0xff. */
+
+ char *p = (char *) g_memdup (aText, aLength);
+
+ /* don't need to reset i */
+ for (; i < aLength; i++)
+ if (!p[i])
+ p[i] = (char) 0xff;
+
+ aText = p;
+ }
+
+ PangoLayout *layout = pango_layout_new(mPangoContext);
+ pango_layout_set_text (layout, aText, aLength);
+ FixupSpaceWidths (layout);
+
+ if (has_nul)
+ g_free ((gpointer) aText);
+
+ return layout;
+}
+
+static void
+utf16_to_utf8 (const PRUnichar* aText, PRUint32 aLength, char *&text, gint &length)
+{
+ gboolean need_copy = FALSE;
+ int i;
+
+ for (i = 0; i < aLength; i++) {
+ if (!aText[i] || IS_LOW_SURROGATE (aText[i]))
+ need_copy = TRUE;
+ else if (IS_HIGH_SURROGATE (aText[i])) {
+ if (i < aLength - 1 && IS_LOW_SURROGATE (aText[i+1]))
+ i++;
+ else
+ need_copy = TRUE;
+ }
+ }
+
+ if (need_copy) {
+
+ /* Pango doesn't correctly handle nuls. We convert them to 0xff. */
+ /* Also "validate" UTF-16 text to make sure conversion doesn't fail. */
+
+ PRUnichar *p = (PRUnichar *) g_memdup (aText, aLength * sizeof (aText[0]));
+
+ /* don't need to reset i */
+ for (i = 0; i < aLength; i++) {
+ if (!p[i] || IS_LOW_SURROGATE (p[i]))
+ p[i] = 0xFFFD;
+ else if (IS_HIGH_SURROGATE (p[i])) {
+ if (i < aLength - 1 && IS_LOW_SURROGATE (aText[i+1]))
+ i++;
+ else
+ p[i] = 0xFFFD;
+ }
+ }
+
+ aText = p;
+ }
+
+ glong items_written;
+ text = g_utf16_to_utf8 (aText, aLength, NULL, &items_written, NULL);
+ length = items_written;
+
+ if (need_copy)
+ g_free ((gpointer) aText);
+
+}
+
/* static */
PangoLanguage *
GetPangoLanguage(nsIAtom *aLangGroup)
--- mozilla.back/gfx/src/gtk/nsFontMetricsPango.h.orig 2006-06-30 01:18:34.000000000 +0200
+++ mozilla.back/gfx/src/gtk/nsFontMetricsPango.h 2007-06-28 15:16:39.000000000 +0200
@@ -37,17 +37,53 @@
*
* ***** END LICENSE BLOCK ***** */
+
#include "nsIFontMetrics.h"
#include "nsIFontEnumerator.h"
#include "nsCRT.h"
#include "nsIAtom.h"
#include "nsString.h"
#include "nsVoidArray.h"
+
+#ifdef PSPANGO
+#include "nsFontMetricsPS.h"
+#else
#include "nsIFontMetricsGTK.h"
+#endif
#include <pango/pango.h>
-class nsFontMetricsPango : public nsIFontMetricsGTK
+#ifdef PSPANGO
+
+#define CONTEXT_ARG_DEF
+#define CONTEXT_ARG_PASS
+#define CONTEXT_ARG_NULL
+#define CONTEXT_AND_SURFACE_ARG_DEF , nsRenderingContextPS *aContext
+#define CONTEXT_AND_SURFACE_ARG_PASS , aContext
+
+#else
+
+#define CONTEXT_ARG_DEF , nsRenderingContextGTK *aContext
+#define CONTEXT_ARG_PASS , aContext
+#define CONTEXT_ARG_NULL , NULL
+#define CONTEXT_AND_SURFACE_ARG_DEF , nsRenderingContextGTK *aContext, nsDrawingSurfaceGTK *aSurface
+#define CONTEXT_AND_SURFACE_ARG_PASS , aContext, aSurface
+
+#endif
+
+
+#ifdef PSPANGO
+
+#define nsFontMetricsPango nsFontMetricsPSPango
+#define PSPANGO_PARENT_CLASS nsFontMetricsPS
+
+#else
+
+#define PSPANGO_PARENT_CLASS nsIFontMetricsGTK
+
+#endif
+
+class nsFontMetricsPango : public PSPANGO_PARENT_CLASS
{
public:
nsFontMetricsPango();
@@ -136,20 +172,30 @@ public:
PRInt32 GetMaxStringLength() { return mMaxStringLength; }
- // nsIFontMetricsGTK (calls from the font rendering layer)
- virtual nsresult GetWidth(const char* aString, PRUint32 aLength,
- nscoord& aWidth,
- nsRenderingContextGTK *aContext);
- virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength,
- nscoord& aWidth, PRInt32 *aFontID,
- nsRenderingContextGTK *aContext);
+ // nsIFontMetrics (calls from the font rendering layer)
- virtual nsresult GetTextDimensions(const PRUnichar* aString,
+#ifdef PSPANGO
+ NS_IMETHOD GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength);
+ NS_IMETHOD GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength);
+#endif
+
+ NS_METHOD GetWidth(const char* aString, PRUint32 aLength,
+ nscoord& aWidth
+ CONTEXT_ARG_DEF);
+ NS_METHOD GetWidth(const PRUnichar* aString, PRUint32 aLength,
+ nscoord& aWidth, PRInt32 *aFontID
+ CONTEXT_ARG_DEF);
+
+ NS_METHOD GetTextDimensions(const char* aString,
+ PRUint32 aLength,
+ nsTextDimensions& aDimensions
+ CONTEXT_ARG_DEF);
+ NS_METHOD GetTextDimensions(const PRUnichar* aString,
PRUint32 aLength,
nsTextDimensions& aDimensions,
- PRInt32* aFontID,
- nsRenderingContextGTK *aContext);
- virtual nsresult GetTextDimensions(const char* aString,
+ PRInt32* aFontID
+ CONTEXT_ARG_DEF);
+ NS_METHOD GetTextDimensions(const char* aString,
PRInt32 aLength,
PRInt32 aAvailWidth,
PRInt32* aBreaks,
@@ -157,9 +203,9 @@ public:
nsTextDimensions& aDimensions,
PRInt32& aNumCharsFit,
nsTextDimensions& aLastWordDimensions,
- PRInt32* aFontID,
- nsRenderingContextGTK *aContext);
- virtual nsresult GetTextDimensions(const PRUnichar* aString,
+ PRInt32* aFontID
+ CONTEXT_ARG_DEF);
+ NS_METHOD GetTextDimensions(const PRUnichar* aString,
PRInt32 aLength,
PRInt32 aAvailWidth,
PRInt32* aBreaks,
@@ -167,38 +213,37 @@ public:
nsTextDimensions& aDimensions,
PRInt32& aNumCharsFit,
nsTextDimensions& aLastWordDimensions,
- PRInt32* aFontID,
- nsRenderingContextGTK *aContext);
+ PRInt32* aFontID
+ CONTEXT_ARG_DEF);
- virtual nsresult DrawString(const char *aString, PRUint32 aLength,
+ NS_METHOD DrawString(const char *aString, PRUint32 aLength,
nscoord aX, nscoord aY,
- const nscoord* aSpacing,
- nsRenderingContextGTK *aContext,
- nsDrawingSurfaceGTK *aSurface);
- virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
+ const nscoord* aSpacing
+ CONTEXT_AND_SURFACE_ARG_DEF);
+
+ NS_METHOD DrawString(const PRUnichar* aString, PRUint32 aLength,
nscoord aX, nscoord aY,
PRInt32 aFontID,
- const nscoord* aSpacing,
- nsRenderingContextGTK *aContext,
- nsDrawingSurfaceGTK *aSurface);
+ const nscoord* aSpacing
+ CONTEXT_AND_SURFACE_ARG_DEF);
#ifdef MOZ_MATHML
- virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength,
- nsBoundingMetrics &aBoundingMetrics,
- nsRenderingContextGTK *aContext);
- virtual nsresult GetBoundingMetrics(const PRUnichar *aString,
+ NS_METHOD GetBoundingMetrics(const char *aString, PRUint32 aLength,
+ nsBoundingMetrics &aBoundingMetrics
+ CONTEXT_ARG_DEF);
+ NS_METHOD GetBoundingMetrics(const PRUnichar *aString,
PRUint32 aLength,
nsBoundingMetrics &aBoundingMetrics,
- PRInt32 *aFontID,
- nsRenderingContextGTK *aContext);
+ PRInt32 *aFontID
+ CONTEXT_ARG_DEF);
#endif /* MOZ_MATHML */
-
+#ifndef PSPANGO
virtual GdkFont* GetCurrentGDKFont(void);
-
- virtual nsresult SetRightToLeftText(PRBool aIsRTL);
+#endif
virtual PRBool GetRightToLeftText();
-
- virtual nsresult GetClusterInfo(const PRUnichar *aText,
+ NS_METHOD SetRightToLeftText(PRBool aIsRTL);
+
+ NS_METHOD GetClusterInfo(const PRUnichar *aText,
PRUint32 aLength,
PRUint8 *aClusterStarts);
@@ -206,32 +251,35 @@ public:
PRUint32 aLength,
nsPoint aPt);
- virtual nsresult GetRangeWidth(const PRUnichar *aText,
+ NS_METHOD GetRangeWidth(const PRUnichar *aText,
PRUint32 aLength,
PRUint32 aStart,
PRUint32 aEnd,
PRUint32 &aWidth);
- virtual nsresult GetRangeWidth(const char *aText,
+ NS_METHOD GetRangeWidth(const char *aText,
PRUint32 aLength,
PRUint32 aStart,
PRUint32 aEnd,
PRUint32 &aWidth);
// get hints for the font
- static PRUint32 GetHints (void);
+#ifndef PSPANGO
+ static
+#endif
+ PRUint32 GetHints (void);
// drawing surface methods
static nsresult FamilyExists (nsIDeviceContext *aDevice,
const nsString &aName);
+
private:
// generic font metrics class bits
nsCStringArray mFontList;
nsAutoVoidArray mFontIsGeneric;
- nsIDeviceContext *mDeviceContext;
nsCOMPtr<nsIAtom> mLangGroup;
nsCString *mGenericFont;
float mPointSize;
@@ -246,6 +294,9 @@ private:
PangoAttrList *mPangoAttrList;
PRBool mIsRTL;
+#ifndef PSPANGO
+ nsIDeviceContext *mDeviceContext;
+
// Cached font metrics
nscoord mXHeight;
nscoord mSuperscriptOffset;
@@ -263,6 +314,7 @@ private:
nscoord mMaxDescent;
nscoord mMaxAdvance;
nscoord mSpaceWidth;
+#endif
nscoord mPangoSpaceWidth;
nscoord mAveCharWidth;
PRInt32 mMaxStringLength;
@@ -274,13 +326,14 @@ private:
static PRBool EnumFontCallback(const nsString &aFamily,
PRBool aIsGeneric, void *aData);
- void DrawStringSlowly(const gchar *aText,
- const PRUnichar *aOrigString,
- PRUint32 aLength,
- GdkDrawable *aDrawable,
- GdkGC *aGC, gint aX, gint aY,
- PangoLayoutLine *aLine,
- const nscoord *aSpacing);
+ void ApplySpacing(const gchar *aText,
+ PRUint32 aLength,
+ PangoLayoutLine *aLine,
+ const nscoord *aSpacing);
+ void ApplySpacing(const PRUnichar *aText,
+ PRUint32 aLength,
+ PangoLayoutLine *aLine,
+ const nscoord *aSpacing);
nsresult GetTextDimensionsInternal(const gchar* aString,
PRInt32 aLength,
@@ -289,10 +342,20 @@ private:
PRInt32 aNumBreaks,
nsTextDimensions& aDimensions,
PRInt32& aNumCharsFit,
- nsTextDimensions& aLastWordDimensions,
- nsRenderingContextGTK *aContext);
+ nsTextDimensions& aLastWordDimensions
+ CONTEXT_ARG_DEF);
+#ifdef MOZ_MATHML
+ void GetBoundingMetricsInternal(PangoLayout *aLayout,
+ nsBoundingMetrics &aBoundingMetrics
+ CONTEXT_ARG_DEF);
+#endif /* MOZ_MATHML */
+
+ void FixupSpaceWidths (PangoLayout *aLayout);
- void FixupSpaceWidths (PangoLayout *aLayout, const char *aString);
+ PangoLayout* GetLayout (const PRUnichar* aText,
+ PRUint32 aLength);
+ PangoLayout* GetLayout (const gchar* aText,
+ PRInt32 aLength);
};
class nsFontEnumeratorPango : public nsIFontEnumerator
Index: firefox.spec
===================================================================
RCS file: /cvs/pkgs/rpms/firefox/F-7/firefox.spec,v
retrieving revision 1.184
retrieving revision 1.185
diff -u -r1.184 -r1.185
--- firefox.spec 3 Jun 2007 19:39:47 -0000 1.184
+++ firefox.spec 9 Jul 2007 08:28:36 -0000 1.185
@@ -12,7 +12,7 @@
Summary: Mozilla Firefox Web browser.
Name: firefox
Version: 2.0.0.4
-Release: 2%{?dist}
+Release: 3%{?dist}
URL: http://www.mozilla.org/projects/firefox/
License: MPL/LGPL
Group: Applications/Internet
@@ -60,6 +60,12 @@
Patch82: firefox-1.5-pango-mathml.patch
Patch83: firefox-1.5-pango-cursor-position.patch
Patch84: firefox-2.0-pango-printing.patch
+Patch85: firefox-2.0-pango-ligatures.patch
+Patch86: firefox-1.5-pango-cursor-position-more.patch
+Patch87: firefox-1.5-pango-justified-range.patch
+Patch88: firefox-1.5-pango-underline.patch
+Patch89: firefox-1.5-xft-rangewidth.patch
+
# Other
Patch100: firefox-1.5-thread-cleanup.patch
@@ -157,6 +163,11 @@
#%patch82 -p1 -b .pango-mathml
%patch83 -p1 -b .pango-cursor-position
%patch84 -p0 -b .pango-printing
+%patch85 -p1 -b .pango-ligatures
+%patch86 -p1 -b .pango-cursor-position-more
+%patch87 -p1 -b .pango-justified-range
+%patch88 -p1 -b .pango-underline
+%patch89 -p1 -b .nopangoxft2
%patch100 -p1 -b .thread-cleanup
%patch102 -p0 -b .theme-change
@@ -418,6 +429,9 @@
#---------------------------------------------------------------------
%changelog
+* Fri Jun 29 2007 Martin Stransky <stransky at redhat.com> 2.0.0.4-3
+- backported pango patches from FC6 (1.5.0.12)
+
* Sun Jun 3 2007 Christopher Aillon <caillon at redhat.com> 2.0.0.4-2
- Properly clean up threads with newer NSPR
- Previous message: rpms/mantis/F-7 .cvsignore, 1.6, 1.7 mantis-README.Fedora, 1.1, 1.2 mantis-httpd.conf, 1.2, 1.3 mantis.spec, 1.15, 1.16 sources, 1.11, 1.12
- Next message: rpms/hunspell-ca/devel .cvsignore, 1.2, 1.3 hunspell-ca.spec, 1.1, 1.2 sources, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the scm-commits
mailing list