From 672783b34bca25b46dccc804a2aeff713b9dcedb Mon Sep 17 00:00:00 2001 From: "mats.palmgren@bredband.net" Date: Fri, 15 Jun 2007 19:13:52 -0700 Subject: [PATCH] Bye bye non-cairo GTK gfx. b=383889 r+sr=vladimir --- allmakefiles.sh | 1 - embedding/config/basebrowser-unix | 3 +- embedding/config/minimo-unix | 3 +- gfx/src/Makefile.in | 5 +- gfx/src/gtk/Makefile.in | 203 - gfx/src/gtk/fontEncoding.properties | 206 - gfx/src/gtk/gfxgtk.pkg | 13 - gfx/src/gtk/mozilla-decoder.cpp | 381 -- gfx/src/gtk/mozilla-decoder.h | 72 - gfx/src/gtk/nsDeviceContextGTK.cpp | 993 --- gfx/src/gtk/nsDeviceContextGTK.h | 121 - gfx/src/gtk/nsDrawingSurfaceGTK.cpp | 365 - gfx/src/gtk/nsDrawingSurfaceGTK.h | 148 - gfx/src/gtk/nsFontMetricsGTK.cpp | 6793 ------------------- gfx/src/gtk/nsFontMetricsGTK.h | 448 -- gfx/src/gtk/nsFontMetricsPango.cpp | 1838 ----- gfx/src/gtk/nsFontMetricsPango.h | 304 - gfx/src/gtk/nsFontMetricsUtils.cpp | 153 - gfx/src/gtk/nsFontMetricsUtils.h | 62 - gfx/src/gtk/nsFontMetricsXft.cpp | 2719 -------- gfx/src/gtk/nsFontMetricsXft.h | 350 - gfx/src/gtk/nsGCCache.cpp | 270 - gfx/src/gtk/nsGCCache.h | 97 - gfx/src/gtk/nsGdkUtils.cpp | 91 - gfx/src/gtk/nsGdkUtils.h | 52 - gfx/src/gtk/nsGfxFactoryGTK.cpp | 300 - gfx/src/gtk/nsGraphicsStateGTK.cpp | 140 - gfx/src/gtk/nsGraphicsStateGTK.h | 90 - gfx/src/gtk/nsIFontMetricsGTK.h | 150 - gfx/src/gtk/nsImageGTK.cpp | 2299 ------- gfx/src/gtk/nsImageGTK.h | 229 - gfx/src/gtk/nsRegionGTK.cpp | 417 -- gfx/src/gtk/nsRegionGTK.h | 81 - gfx/src/gtk/nsRegionGTK2.cpp | 381 -- gfx/src/gtk/nsRenderingContextGTK.cpp | 1473 ---- gfx/src/gtk/nsRenderingContextGTK.h | 308 - gfx/src/gtk/pangoFontEncoding.properties | 120 - gfx/src/gtk/xregion.h | 177 - gfx/src/x11shared/README | 6 - gfx/src/x11shared/dbyte_special_chars.ccmap | 178 - gfx/src/x11shared/nsAntiAliasedGlyph.cpp | 235 - gfx/src/x11shared/nsAntiAliasedGlyph.h | 85 - gfx/src/x11shared/nsFT2FontCatalog.cpp | 2477 ------- gfx/src/x11shared/nsFT2FontCatalog.h | 189 - gfx/src/x11shared/nsFT2FontNode.cpp | 449 -- gfx/src/x11shared/nsFT2FontNode.h | 66 - gfx/src/x11shared/nsFontDebug.h | 105 - gfx/src/x11shared/nsFontFreeType.cpp | 967 --- gfx/src/x11shared/nsFontFreeType.h | 121 - gfx/src/x11shared/nsNameValuePairDB.cpp | 543 -- gfx/src/x11shared/nsNameValuePairDB.h | 94 - gfx/src/x11shared/nsX11AlphaBlend.cpp | 1169 ---- gfx/src/x11shared/nsX11AlphaBlend.h | 106 - gfx/src/x11shared/nsXFont.h | 66 - gfx/src/x11shared/nsXFontAAScaledBitmap.cpp | 1352 ---- gfx/src/x11shared/nsXFontAAScaledBitmap.h | 126 - gfx/src/x11shared/nsXFontNormal.cpp | 152 - gfx/src/x11shared/nsXFontNormal.h | 73 - toolkit/library/libxul-config.mk | 3 - toolkit/library/nsStaticXULComponents.cpp | 4 +- widget/src/gtk2/Makefile.in | 17 +- widget/src/gtk2/nsDeviceContextSpecG.cpp | 14 - widget/src/gtk2/nsDeviceContextSpecG.h | 13 - widget/src/gtk2/nsDragService.cpp | 8 +- widget/src/gtk2/nsImageToPixbuf.cpp | 11 - widget/src/gtk2/nsImageToPixbuf.h | 2 - widget/src/gtk2/nsNativeThemeGTK.cpp | 54 - widget/src/gtk2/nsWindow.cpp | 20 +- widget/src/gtk2/nsWindow.h | 4 - xpinstall/packager/packages-unix | 3 +- 70 files changed, 16 insertions(+), 30552 deletions(-) delete mode 100644 gfx/src/gtk/Makefile.in delete mode 100644 gfx/src/gtk/fontEncoding.properties delete mode 100644 gfx/src/gtk/gfxgtk.pkg delete mode 100644 gfx/src/gtk/mozilla-decoder.cpp delete mode 100644 gfx/src/gtk/mozilla-decoder.h delete mode 100644 gfx/src/gtk/nsDeviceContextGTK.cpp delete mode 100644 gfx/src/gtk/nsDeviceContextGTK.h delete mode 100644 gfx/src/gtk/nsDrawingSurfaceGTK.cpp delete mode 100644 gfx/src/gtk/nsDrawingSurfaceGTK.h delete mode 100644 gfx/src/gtk/nsFontMetricsGTK.cpp delete mode 100644 gfx/src/gtk/nsFontMetricsGTK.h delete mode 100644 gfx/src/gtk/nsFontMetricsPango.cpp delete mode 100644 gfx/src/gtk/nsFontMetricsPango.h delete mode 100644 gfx/src/gtk/nsFontMetricsUtils.cpp delete mode 100644 gfx/src/gtk/nsFontMetricsUtils.h delete mode 100644 gfx/src/gtk/nsFontMetricsXft.cpp delete mode 100644 gfx/src/gtk/nsFontMetricsXft.h delete mode 100644 gfx/src/gtk/nsGCCache.cpp delete mode 100644 gfx/src/gtk/nsGCCache.h delete mode 100644 gfx/src/gtk/nsGdkUtils.cpp delete mode 100644 gfx/src/gtk/nsGdkUtils.h delete mode 100644 gfx/src/gtk/nsGfxFactoryGTK.cpp delete mode 100644 gfx/src/gtk/nsGraphicsStateGTK.cpp delete mode 100644 gfx/src/gtk/nsGraphicsStateGTK.h delete mode 100644 gfx/src/gtk/nsIFontMetricsGTK.h delete mode 100644 gfx/src/gtk/nsImageGTK.cpp delete mode 100644 gfx/src/gtk/nsImageGTK.h delete mode 100644 gfx/src/gtk/nsRegionGTK.cpp delete mode 100644 gfx/src/gtk/nsRegionGTK.h delete mode 100644 gfx/src/gtk/nsRegionGTK2.cpp delete mode 100644 gfx/src/gtk/nsRenderingContextGTK.cpp delete mode 100644 gfx/src/gtk/nsRenderingContextGTK.h delete mode 100644 gfx/src/gtk/pangoFontEncoding.properties delete mode 100644 gfx/src/gtk/xregion.h delete mode 100644 gfx/src/x11shared/README delete mode 100755 gfx/src/x11shared/dbyte_special_chars.ccmap delete mode 100644 gfx/src/x11shared/nsAntiAliasedGlyph.cpp delete mode 100644 gfx/src/x11shared/nsAntiAliasedGlyph.h delete mode 100644 gfx/src/x11shared/nsFT2FontCatalog.cpp delete mode 100644 gfx/src/x11shared/nsFT2FontCatalog.h delete mode 100644 gfx/src/x11shared/nsFT2FontNode.cpp delete mode 100644 gfx/src/x11shared/nsFT2FontNode.h delete mode 100644 gfx/src/x11shared/nsFontDebug.h delete mode 100644 gfx/src/x11shared/nsFontFreeType.cpp delete mode 100644 gfx/src/x11shared/nsFontFreeType.h delete mode 100644 gfx/src/x11shared/nsNameValuePairDB.cpp delete mode 100644 gfx/src/x11shared/nsNameValuePairDB.h delete mode 100644 gfx/src/x11shared/nsX11AlphaBlend.cpp delete mode 100644 gfx/src/x11shared/nsX11AlphaBlend.h delete mode 100644 gfx/src/x11shared/nsXFont.h delete mode 100644 gfx/src/x11shared/nsXFontAAScaledBitmap.cpp delete mode 100644 gfx/src/x11shared/nsXFontAAScaledBitmap.h delete mode 100644 gfx/src/x11shared/nsXFontNormal.cpp delete mode 100644 gfx/src/x11shared/nsXFontNormal.h diff --git a/allmakefiles.sh b/allmakefiles.sh index a7eb43cc93f1..ee6143cfe92b 100755 --- a/allmakefiles.sh +++ b/allmakefiles.sh @@ -155,7 +155,6 @@ gfx/idl/Makefile gfx/public/Makefile gfx/src/Makefile gfx/src/beos/Makefile -gfx/src/gtk/Makefile gfx/src/ps/Makefile gfx/src/psshared/Makefile gfx/src/photon/Makefile diff --git a/embedding/config/basebrowser-unix b/embedding/config/basebrowser-unix index 38c16d772ce0..3788a6a0cf27 100644 --- a/embedding/config/basebrowser-unix +++ b/embedding/config/basebrowser-unix @@ -50,10 +50,9 @@ libgkgfx.so libgtksuperwin.so libgtkembedmoz.so libgfxpsshar.so -components/libgfx_gtk.so +components/libgkgfxthebes.so components/libgfxps.so components/gfx.xpt -components/libwidget_gtk.so components/libwidget_gtk2.so components/widget.xpt diff --git a/embedding/config/minimo-unix b/embedding/config/minimo-unix index ab317ebd362b..266ad55a4f67 100644 --- a/embedding/config/minimo-unix +++ b/embedding/config/minimo-unix @@ -42,10 +42,9 @@ libgkgfx.so libgtksuperwin.so libgtkembedmoz.so libgfxpsshar.so -components/libgfx_gtk.so +components/libgkgfxthebes.so components/libgfxps.so components/gfx.xpt -components/libwidget_gtk.so components/libwidget_gtk2.so components/widget.xpt diff --git a/gfx/src/Makefile.in b/gfx/src/Makefile.in index acdc8f761e73..a128ece8d39f 100644 --- a/gfx/src/Makefile.in +++ b/gfx/src/Makefile.in @@ -77,9 +77,6 @@ endif ifdef MOZ_ENABLE_CAIRO_GFX DIRS += thebes else - ifdef MOZ_ENABLE_GTK2 - DIRS += gtk - endif ifdef MOZ_ENABLE_PHOTON DIRS += photon endif @@ -108,7 +105,7 @@ ifeq (,$(filter windows,$(MOZ_WIDGET_TOOLKIT))) REQUIRES += uconv endif -ifneq (,$(filter gtk2 beos windows os2,$(MOZ_WIDGET_TOOLKIT))) +ifneq (,$(filter beos windows os2,$(MOZ_WIDGET_TOOLKIT))) CPPSRCS += imgScaler.cpp endif diff --git a/gfx/src/gtk/Makefile.in b/gfx/src/gtk/Makefile.in deleted file mode 100644 index ffc21095b8fa..000000000000 --- a/gfx/src/gtk/Makefile.in +++ /dev/null @@ -1,203 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Netscape Communications Corporation. -# Portions created by the Initial Developer are Copyright (C) 1998 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Roland Mainz -# -# Alternatively, the contents of this file may be used under the terms of -# either of the GNU General Public License Version 2 or later (the "GPL"), -# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = gfx -LIBRARY_NAME = gfx_gtk -EXPORT_LIBRARY = 1 -IS_COMPONENT = 1 -MODULE_NAME = nsGfxGTKModule -GRE_MODULE = 1 -LIBXUL_LIBRARY = 1 - -REQUIRES = xpcom \ - string \ - widget \ - view \ - util \ - pref \ - uconv \ - unicharutil \ - locale \ - necko \ - $(NULL) - -# Sun's Complex Text Layout support -ifdef SUNCTL -REQUIRES += ctl -endif - -# Code used by the GTK+ gfx module -X11SHARED_LCPPSRCS = \ - nsAntiAliasedGlyph.cpp \ - nsX11AlphaBlend.cpp \ - nsXFontAAScaledBitmap.cpp \ - nsXFontNormal.cpp \ - $(NULL) - -ifdef MOZ_ENABLE_FREETYPE2 -X11SHARED_LCPPSRCS += \ - nsFontFreeType.cpp \ - nsFT2FontNode.cpp \ - nsFT2FontCatalog.cpp \ - nsNameValuePairDB.cpp \ - $(NULL) -endif - -CPPSRCS = \ - nsDeviceContextGTK.cpp \ - nsDrawingSurfaceGTK.cpp \ - nsGfxFactoryGTK.cpp \ - nsGraphicsStateGTK.cpp \ - nsImageGTK.cpp \ - nsGCCache.cpp \ - nsRenderingContextGTK.cpp \ - nsFontMetricsUtils.cpp \ - $(NULL) - -ifdef MOZ_ENABLE_COREXFONTS -CPPSRCS += \ - $(X11SHARED_LCPPSRCS) \ - nsFontMetricsGTK.cpp \ - nsGdkUtils.cpp -endif - -ifdef MOZ_ENABLE_XFT -CPPSRCS += \ - nsFontMetricsXft.cpp -endif - -ifdef MOZ_ENABLE_PANGO -CPPSRCS += \ - nsFontMetricsPango.cpp \ - mozilla-decoder.cpp -endif - -ifdef MOZ_ENABLE_GTK2 -CPPSRCS += \ - nsRegionGTK2.cpp \ - $(NULL) -endif - -GARBAGE += $(X11SHARED_LCPPSRCS) $(XPU_LCSRCS) $(wildcard *.$(OBJ_SUFFIX)) - -ifdef MOZ_ENABLE_FREETYPE2 -# the SHARED_LIBRARY_LIBS line must be before the rules.mk include -SHARED_LIBRARY_LIBS += ../freetype/$(LIB_PREFIX)gfxft2_s.$(LIB_SUFFIX) -endif - -EXTRA_DSO_LDOPTS = ../shared/$(LIB_PREFIX)gfxshared_s.$(LIB_SUFFIX) - -include $(topsrcdir)/config/rules.mk - -ifdef MOZ_ENABLE_XINERAMA -GFX_XINERAMA_LIBS += $(MOZ_XINERAMA_LIBS) -endif - -ifdef MOZ_ENABLE_XFT -EXTRA_DSO_LDOPTS += $(FT2_LIBS) - -libs:: fontEncoding.properties pangoFontEncoding.properties - $(INSTALL) $^ $(DIST)/bin/res/fonts - -install:: fontEncoding.properties pangoFontEncoding.properties - $(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/res/fonts -endif - -ifdef MOZ_ENABLE_GTK2 -EXTRA_DSO_LDOPTS += \ - $(LIBS_DIR) \ - -lgkgfx \ - $(GFX_XINERAMA_LIBS) \ - $(MOZ_JS_LIBS) \ - $(MOZ_UNICHARUTIL_LIBS) \ - $(MOZ_COMPONENT_LIBS) \ - $(NULL) -endif - -ifdef MOZ_ENABLE_PANGO -EXTRA_DSO_LDOPTS += $(MOZ_PANGO_LIBS) -endif - -EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(MOZ_XFT_LIBS) $(MOZ_GTK2_LIBS) -CXXFLAGS += $(MOZ_GTK2_CFLAGS) -CFLAGS += $(MOZ_GTK2_CFLAGS) - -ifeq ($(OS_ARCH), SunOS) -ifndef GNU_CC -# When using Sun's WorkShop compiler, including -# /wherever/workshop-5.0/SC5.0/include/CC/std/time.h -# causes most of these compiles to fail with: -# line 29: Error: Multiple declaration for std::tm. -# So, this gets around the problem. -DEFINES += -D_TIME_H=1 -endif -endif - -ifeq ($(OS_ARCH), OpenVMS) -DEFINES += -DGENERIC_MOTIF_REDEFINES -OS_CXXFLAGS += -Wc,warn=disa=NOSIMPINT -endif - -ifdef MOZ_ENABLE_POSTSCRIPT -DEFINES += -DUSE_POSTSCRIPT -EXTRA_DSO_LDOPTS += -lgfxpsshar -endif - -LOCAL_INCLUDES = \ - -I../.. \ - -I$(srcdir)/. \ - -I$(srcdir)/.. \ - -I$(srcdir)/../shared \ - -I$(srcdir)/../x11shared \ - $(MOZ_XFT_CFLAGS) \ - $(NULL) - -ifdef MOZ_ENABLE_FREETYPE2 -INCLUDES += $(FT2_CFLAGS) -LOCAL_INCLUDES += -I$(srcdir)/../freetype -endif - -export:: $(addprefix $(srcdir)/../x11shared/,$(X11SHARED_LCPPSRCS)) - $(INSTALL) $^ . diff --git a/gfx/src/gtk/fontEncoding.properties b/gfx/src/gtk/fontEncoding.properties deleted file mode 100644 index ac21feed527a..000000000000 --- a/gfx/src/gtk/fontEncoding.properties +++ /dev/null @@ -1,206 +0,0 @@ -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is Mozilla MathML Project. -# -# The Initial Developer of the Original Code is -# The University of Queensland. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Roger B. Sidje -# Jungshik Shin -# -# 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 -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -# LOCALIZATION NOTE: FILE -# Do not translate anything in this file - -# This is a list of encodings used for special *symbolic fonts* (not documents) # for which we have converters (i.e., the intl/uconv library contains encoding # tables that provide a mapping of characters to the indices of the desired -# glyph shapes within these symbolic fonts). -# -# This file also lists truetype cmap tables for single byte ('narrow') special -# *symbolic fonts*. At the moment, only two values, 'mac_roman' -# and 'unicode' are recognized. These cmaps are used to translate custom font -# codes obtained through converters in intl/uconv library into glyph indices of # fonts with Freetype library. Do not change the value unless you're familiar -# with the internals of Freetype and Mozilla-Xft. If you're interested, -# see -# http://freetype.sourceforge.net/freetype2/docs/reference/ft2-base_interface.html#FT_Encoding -# and -# http://bugzilla.mozilla.org/show_bug.cgi?id=176290 -# -# For each 'key = value' pair in this list: -# -# - the 'key' is a lower case ASCII with the *name of the font*, and the -# encoding type (e.g., .ttf for TrueType, and .t1 for Type 1). Note that -# the *name of a font* is not necessarily the *name of the file* that contains -# the font... All whitespace should be stripped from the name. -# For truetype cmaps, use .ftcmap in place of .ttf or .t1. -# -# - the 'value' is the case-sensitive charset string used when setting up the -# corresponding Unicode Converter in the intl/uconv library. -# - the 'value' for ftcmap is either mac_roman -# or unicode. - -# If you have Symbol (Adobe) type 1 font, keep the following lines -# commented out (you do NOT need them). However, with truetype Symbol -# font, you do need them. - -# Symbol font -#encoding.symbol.ttf = Adobe-Symbol-Encoding -#encoding.symbol.ftcmap = mac_roman - -# TeX's Computer Modern fonts (Roman, Math Italic, Symbol and Extension) - -encoding.cmr10.ttf = x-ttf-cmr -encoding.cmmi10.ttf = x-ttf-cmmi -encoding.cmsy10.ttf = x-ttf-cmsy -encoding.cmex10.ttf = x-ttf-cmex - -encoding.cmr10.ftcmap = unicode -encoding.cmmi10.ftcmap = unicode -encoding.cmsy10.ftcmap = unicode -encoding.cmex10.ftcmap = unicode - -# Mathematica fonts - -encoding.math1.ttf = x-mathematica1 -encoding.math1-bold.ttf = x-mathematica1 -encoding.math1mono.ttf = x-mathematica1 -encoding.math1mono-bold.ttf = x-mathematica1 - -encoding.math2.ttf = x-mathematica2 -encoding.math2-bold.ttf = x-mathematica2 -encoding.math2mono.ttf = x-mathematica2 -encoding.math2mono-bold.ttf = x-mathematica2 - -encoding.math3.ttf = x-mathematica3 -encoding.math3-bold.ttf = x-mathematica3 -encoding.math3mono.ttf = x-mathematica3 -encoding.math3mono-bold.ttf = x-mathematica3 - -encoding.math4.ttf = x-mathematica4 -encoding.math4-bold.ttf = x-mathematica4 -encoding.math4mono.ttf = x-mathematica4 -encoding.math4mono-bold.ttf = x-mathematica4 - -encoding.math5.ttf = x-mathematica5 -encoding.math5-bold.ttf = x-mathematica5 -encoding.math5bold.ttf = x-mathematica5 -encoding.math5mono.ttf = x-mathematica5 -encoding.math5mono-bold.ttf = x-mathematica5 -encoding.math5monobold.ttf = x-mathematica5 - -encoding.math1.ftcmap = mac_roman -encoding.math1-bold.ftcmap = mac_roman -encoding.math1mono.ftcmap = mac_roman -encoding.math1mono-bold.ftcmap = mac_roman - -encoding.math2.ftcmap = mac_roman -encoding.math2-bold.ftcmap = mac_roman -encoding.math2mono.ftcmap = mac_roman -encoding.math2mono-bold.ftcmap = mac_roman - -encoding.math3.ftcmap = mac_roman -encoding.math3-bold.ftcmap = mac_roman -encoding.math3mono.ftcmap = mac_roman -encoding.math3mono-bold.ftcmap = mac_roman - -encoding.math4.ftcmap = mac_roman -encoding.math4-bold.ftcmap = mac_roman -encoding.math4mono.ftcmap = mac_roman -encoding.math4mono-bold.ftcmap = mac_roman - -encoding.math5.ftcmap = mac_roman -encoding.math5-bold.ftcmap = mac_roman -encoding.math5bold.ftcmap = mac_roman -encoding.math5mono.ftcmap = mac_roman -encoding.math5mono-bold.ftcmap = mac_roman -encoding.math5monobold.ftcmap = mac_roman - -# MathType Extra -encoding.mtextra.ttf = x-mtextra -encoding.mtextra.ftcmap = mac_roman - -# Tamil fonts (TSCII encoding : see -# http://www.tscii.org and http://www.tamil.net). Not all 'TSCII fonts' are -# equal. I've confirmed the following fonts work, but other 'TSCII fonts' may -# not work. These fonts have pseudo-Unicode cmap with TSCII -# interpreted as Windows-1252. -# -encoding.tsc_paranarpdf.ttf = x-tamilttf-0.wide -encoding.tsc_paranbold.ttf = x-tamilttf-0.wide -encoding.tsc_paranarho.ttf = x-tamilttf-0.wide -encoding.tsc_kannadaasan.ttf = x-tamilttf-0.wide -encoding.tscu_comic.ttf = x-tamilttf-0.wide -encoding.tscu_times.ttf = x-tamilttf-0.wide -encoding.tscu_paranar.ttf = x-tamilttf-0.wide -encoding.tscu_paranarbold.ttf = x-tamilttf-0.wide - - -# These two fonts have conflicting MacRoman and Unicode Cmaps -# that get fontconfig confused. -#encoding.tsc_avarangal.ttf = x-tamilttf-0.wide -#encoding.tsc_avarangalfxd.ttf = x-tamilttf-0.wide - -# These two fonts don't have Unicode cmap but have pseudo-Apple Roman cmap -# with TSCII assignment. -encoding.tsc_aandaal.ttf = x-tscii-0 -encoding.tsc_aandaal.ftcmap = mac_roman -encoding.tsc_aparanarpdf.ttf = x-tscii-0 -encoding.tsc_aparanarpdf.ftcmap = mac_roman - - -# The suffix '.wide' has to be added to encoding names to identify -# these fonts as 'wide' non-Unicode fonts. - -# Korean Jamo TTFs -encoding.unbatang.ttf = x-koreanjamo-0.wide - -# Thai TTFs -# glyph arrangement : TIS620-2 Windows encoding, -# code points used : Unicode Thai block + about 10 PUA code points in U+F700, -# coverage : US-ASCII, Thai (U+0E00-U+0E07F), punctuation marks -# U+2018, U+2019, U+201c, U+201d, U+2022, U+2013, U+2014 ) -# -# These familes of fonts and other fonts with the same PUA assignment -# are included as a part of Thai language support in most Linux distributions. -# These lines have to be commented out by default because the encoder for -# x-thaittf-0 is only available with 'enable-ctl' which is not turned on -# by default. -#encoding.norasi.ttf = x-thaittf-0.wide -#encoding.garuda.ttf = x-thaittf-0.wide -#encoding.dbthaitext.ttf = x-thaittf-0.wide - -# SunIndic fonts. -# glyph arrangement : Nominal glyphs for Indic scripts at their Unicode code -# points along with presentation forms in PUA -# coverage : US-ASCII, Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, -# Tamil, Telugu, Kanada, Malayalam -# Note : Currently only Devanagari is supported with this encoding. -# Two fonts in this family is available for free download at -# . -encoding.saraswati5.ttf = x-sun-unicode-india-0.wide diff --git a/gfx/src/gtk/gfxgtk.pkg b/gfx/src/gtk/gfxgtk.pkg deleted file mode 100644 index 4b1041664379..000000000000 --- a/gfx/src/gtk/gfxgtk.pkg +++ /dev/null @@ -1,13 +0,0 @@ -[gecko] -#if SHARED_LIBRARY -dist/bin/components/@SHARED_LIBRARY@ -#else -!staticcomp @LIBRARY@ @MODULE_NAME@ -#endif -#if MOZ_ENABLE_XFT -dist/bin/res/fonts/fontEncoding.properties -#endif -#if MOZ_ENABLE_PANGO -dist/bin/res/fonts/pangoFontEncoding.properties -#endif - diff --git a/gfx/src/gtk/mozilla-decoder.cpp b/gfx/src/gtk/mozilla-decoder.cpp deleted file mode 100644 index 04aa796ca971..000000000000 --- a/gfx/src/gtk/mozilla-decoder.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Christopher Blizzard - * . Portions created by the Initial Developer - * are Copyright (C) 2004 the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#define PANGO_ENABLE_BACKEND -#define PANGO_ENABLE_ENGINE - -#include "mozilla-decoder.h" -#include -#include -#include - -#include "nsString.h" -#include "nsIPersistentProperties2.h" -#include "nsNetUtil.h" -#include "nsReadableUtils.h" -#include "nsICharsetConverterManager.h" -#include "nsICharRepresentable.h" -#include "nsCompressedCharMap.h" - -#undef DEBUG_CUSTOM_ENCODER - -G_DEFINE_TYPE (MozillaDecoder, mozilla_decoder, PANGO_TYPE_FC_DECODER) - -MozillaDecoder *mozilla_decoder_new (void); - -static FcCharSet *mozilla_decoder_get_charset (PangoFcDecoder *decoder, - PangoFcFont *fcfont); -static PangoGlyph mozilla_decoder_get_glyph (PangoFcDecoder *decoder, - PangoFcFont *fcfont, - guint32 wc); - -static PangoFcDecoder *mozilla_find_decoder (FcPattern *pattern, - gpointer user_data); - -typedef struct _MozillaDecoderPrivate MozillaDecoderPrivate; - -#define MOZILLA_DECODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderPrivate)) - -struct _MozillaDecoderPrivate { - char *family; - char *encoder; - char *cmap; - gboolean is_wide; - FcCharSet *charset; - nsCOMPtr uEncoder; -}; - -static nsICharsetConverterManager *gCharsetManager = NULL; - -static NS_DEFINE_CID(kCharsetConverterManagerCID, - NS_ICHARSETCONVERTERMANAGER_CID); - -// Hash tables that hold the custom encodings and custom cmaps used in -// various fonts. -GHashTable *encoder_hash = NULL; -GHashTable *cmap_hash = NULL; -GHashTable *wide_hash = NULL; - -void -mozilla_decoder_init (MozillaDecoder *decoder) -{ -} - -void -mozilla_decoder_class_init (MozillaDecoderClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS(klass); - PangoFcDecoderClass *parent_class = PANGO_FC_DECODER_CLASS (klass); - - /* object_class->finalize = test_finalize; */ - - parent_class->get_charset = mozilla_decoder_get_charset; - parent_class->get_glyph = mozilla_decoder_get_glyph; - - g_type_class_add_private (object_class, sizeof (MozillaDecoderPrivate)); -} - -MozillaDecoder * -mozilla_decoder_new(void) -{ - return (MozillaDecoder *)g_object_new(MOZILLA_TYPE_DECODER, NULL); -} - -#ifdef DEBUG_CUSTOM_ENCODER -void -dump_hash(char *key, char *val, void *arg) -{ - printf("%s -> %s\n", key, val); -} -#endif - -/** - * mozilla_decoders_init: - * - * #mozilla_decoders_init: - * - * This initializes all of the application-specific custom decoders - * that Mozilla uses. This should only be called once during the - * lifetime of the application. - * - * Return value: zero on success, not zero on failure. - * - **/ - -int -mozilla_decoders_init(void) -{ - static PRBool initialized = PR_FALSE; - if (initialized) - return 0; - - PangoContext* context = gdk_pango_context_get (); - PangoFontMap* fontmap = pango_context_get_font_map (context); - g_object_unref (context); - - if (!PANGO_IS_FC_FONT_MAP (fontmap)) - return -1; - - encoder_hash = g_hash_table_new(g_str_hash, g_str_equal); - cmap_hash = g_hash_table_new(g_str_hash, g_str_equal); - wide_hash = g_hash_table_new(g_str_hash, g_str_equal); - - PRBool dumb = PR_FALSE; - nsCOMPtr props; - nsCOMPtr encodeEnum; - - NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(props), - NS_LITERAL_CSTRING("resource://gre/res/fonts/pangoFontEncoding.properties")); - - if (!props) - goto loser; - - // Enumerate the properties in this file and figure out all of the - // fonts for which we have custom encodings. - props->Enumerate(getter_AddRefs(encodeEnum)); - if (!encodeEnum) - goto loser; - - while (encodeEnum->HasMoreElements(&dumb), dumb) { - nsCOMPtr prop; - encodeEnum->GetNext(getter_AddRefs(prop)); - if (!prop) - goto loser; - - nsCAutoString name; - prop->GetKey(name); - nsAutoString value; - prop->GetValue(value); - - if (!StringBeginsWith(name, NS_LITERAL_CSTRING("encoding."))) { - printf("string doesn't begin with encoding?\n"); - continue; - } - - name = Substring(name, 9); - - if (StringEndsWith(name, NS_LITERAL_CSTRING(".ttf"))) { - name = Substring(name, 0, name.Length() - 4); - - // Strip off a .wide if it's there. - if (StringEndsWith(value, NS_LITERAL_STRING(".wide"))) { - g_hash_table_insert(wide_hash, g_strdup(name.get()), - g_strdup("wide")); - value = Substring(value, 0, name.Length() - 5); - } - - g_hash_table_insert(encoder_hash, - g_strdup(name.get()), - g_strdup(NS_ConvertUTF16toUTF8(value).get())); - } - else if (StringEndsWith(name, NS_LITERAL_CSTRING(".ftcmap"))) { - name = Substring(name, 0, name.Length() - 7); - g_hash_table_insert(cmap_hash, - g_strdup(name.get()), - g_strdup(NS_ConvertUTF16toUTF8(value).get())); - } - else { - printf("unknown suffix used for mapping\n"); - } - } - - pango_fc_font_map_add_decoder_find_func(PANGO_FC_FONT_MAP(fontmap), - mozilla_find_decoder, - NULL, - NULL); - - initialized = PR_TRUE; - -#ifdef DEBUG_CUSTOM_ENCODER - printf("*** encoders\n"); - g_hash_table_foreach(encoder_hash, (GHFunc)dump_hash, NULL); - - printf("*** cmaps\n"); - g_hash_table_foreach(cmap_hash, (GHFunc)dump_hash, NULL); -#endif - - return 0; - - loser: - return -1; -} - -FcCharSet * -mozilla_decoder_get_charset (PangoFcDecoder *decoder, - PangoFcFont *fcfont) -{ - MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder); - - if (priv->charset) - return priv->charset; - - // First time this has been accessed. Populate the charset. - priv->charset = FcCharSetCreate(); - - if (!gCharsetManager) { - CallGetService(kCharsetConverterManagerCID, &gCharsetManager); - } - - nsCOMPtr encoder; - nsCOMPtr represent; - - if (!gCharsetManager) - goto end; - - gCharsetManager->GetUnicodeEncoderRaw(priv->encoder, getter_AddRefs(encoder)); - if (!encoder) - goto end; - - encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?'); - - priv->uEncoder = encoder; - - represent = do_QueryInterface(encoder); - if (!represent) - goto end; - - PRUint32 map[UCS2_MAP_LEN]; - memset(map, 0, sizeof(map)); - - represent->FillInfo(map); - - for (int i = 0; i < NUM_UNICODE_CHARS; i++) { - if (IS_REPRESENTABLE(map, i)) - FcCharSetAddChar(priv->charset, i); - } - - end: - return priv->charset; -} - -PangoGlyph -mozilla_decoder_get_glyph (PangoFcDecoder *decoder, - PangoFcFont *fcfont, - guint32 wc) -{ - MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder); - - PangoGlyph retval = 0; - PRUnichar inchar = wc; - PRInt32 inlen = 1; - char outchar[2] = {0,0}; - PRInt32 outlen = 2; - - priv->uEncoder->Convert(&inchar, &inlen, outchar, &outlen); - if (outlen != 1) { - printf("Warning: mozilla_decoder_get_glyph doesn't support more than one character conversions.\n"); - return 0; - } - - FT_Face face = pango_fc_font_lock_face(fcfont); - -#ifdef DEBUG_CUSTOM_ENCODER - char *filename; - FcPatternGetString(fcfont->font_pattern, FC_FILE, 0, (FcChar8 **)&filename); - printf("filename is %s\n", filename); -#endif - - // Make sure to set the right charmap before trying to get the - // glyph - if (priv->cmap) { - if (!strcmp(priv->cmap, "mac_roman")) { - FT_Select_Charmap(face, ft_encoding_apple_roman); - } - else if (!strcmp(priv->cmap, "unicode")) { - FT_Select_Charmap(face, ft_encoding_unicode); - } - else { - printf("Warning: Invalid charmap entry for family %s\n", - priv->family); - } - } - - // Standard 8 bit to glyph translation - if (!priv->is_wide) { - FcChar32 blah = PRUint8(outchar[0]); - retval = FT_Get_Char_Index(face, blah); -#ifdef DEBUG_CUSTOM_ENCODER - printf("wc 0x%x outchar[0] 0x%x index 0x%x retval 0x%x face %p\n", - wc, outchar[0], blah, retval, (void *)face); -#endif - } - else { - printf("Warning: We don't support .wide fonts!\n"); - retval = 0; - } - - pango_fc_font_unlock_face(fcfont); - - return retval; -} - -PangoFcDecoder * -mozilla_find_decoder (FcPattern *pattern, gpointer user_data) -{ - // Compare the family name of the font that's been opened to see - // if we have a custom decoder. - const char *orig = NULL; - FcPatternGetString(pattern, FC_FAMILY, 0, (FcChar8 **)&orig); - - nsCAutoString family; - family.Assign(orig); - - family.StripWhitespace(); - ToLowerCase(family); - - char *encoder = (char *)g_hash_table_lookup(encoder_hash, family.get()); - if (!encoder) - return NULL; - - MozillaDecoder *decoder = mozilla_decoder_new(); - - MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder); - - priv->family = g_strdup(family.get()); - priv->encoder = g_strdup(encoder); - - char *cmap = (char *)g_hash_table_lookup(cmap_hash, family.get()); - if (cmap) - priv->cmap = g_strdup(cmap); - - char *wide = (char *)g_hash_table_lookup(wide_hash, family.get()); - if (wide) - priv->is_wide = TRUE; - - return PANGO_FC_DECODER(decoder); -} diff --git a/gfx/src/gtk/mozilla-decoder.h b/gfx/src/gtk/mozilla-decoder.h deleted file mode 100644 index 3b78948b13f9..000000000000 --- a/gfx/src/gtk/mozilla-decoder.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Christopher Blizzard - * . Portions created by the Initial Developer - * are Copyright (C) 2004 the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _MOZILLA_DECODER_H -#define _MOZILLA_DECODER_H - -#include - -G_BEGIN_DECLS - -#define MOZILLA_TYPE_DECODER (mozilla_decoder_get_type()) -#define MOZILLA_DECODER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOZILLA_TYPE_DECODER, MozillaDecoder)) -#define MOZILLA_IS_DECODER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOZILLA_TYPE_DECODER)) - -typedef struct _MozillaDecoder MozillaDecoder; -typedef struct _MozillaDecoderClass MozillaDecoderClass; - -#define MOZILLA_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOZILLA_TYPE_DECODER, MozillaDecoderClass)) -#define MOZILLA_IS_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOZILLA_TYPE_DECODER)) -#define MOZILLA_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderClass)) - -struct _MozillaDecoder -{ - PangoFcDecoder parent_instance; -}; - -struct _MozillaDecoderClass -{ - PangoFcDecoderClass parent_class; -}; - -GType mozilla_decoder_get_type (void); -int mozilla_decoders_init (void); - -G_END_DECLS - -#endif /*_MOZILLA_DECODER_H */ diff --git a/gfx/src/gtk/nsDeviceContextGTK.cpp b/gfx/src/gtk/nsDeviceContextGTK.cpp deleted file mode 100644 index a6a5ed512681..000000000000 --- a/gfx/src/gtk/nsDeviceContextGTK.cpp +++ /dev/null @@ -1,993 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -// vim:cindent:ts=2:et:sw=2: -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Roland Mainz - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include - -#include "nspr.h" -#include "nsIPref.h" -#include "nsIServiceManager.h" -#include "nsCRT.h" - -#include "nsDeviceContextGTK.h" -#include "nsGfxCIID.h" - -#ifdef USE_POSTSCRIPT -#include "nsGfxPSCID.h" -#include "nsIDeviceContextPS.h" -#endif /* USE_POSTSCRIPT */ - -#include "nsFontMetricsUtils.h" - -#include -#include - -#ifdef MOZ_WIDGET_GTK2 -#include -#include -#include -#endif - -#ifdef MOZ_ENABLE_XFT -#include "nsFontMetricsUtils.h" -#include -#include - -static PRInt32 GetXftDPI(void); -#endif - -#include - -#include "nsIDeviceContextSpec.h" - -static PRInt32 GetOSDPI(void); - -#define GDK_DEFAULT_FONT1 "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1" -#define GDK_DEFAULT_FONT2 "-*-fixed-medium-r-*-*-*-120-*-*-*-*-*-*" - -/** - * A singleton instance of nsSystemFontsGTK is created by the first - * device context and destroyed by the module destructor. - */ -class nsSystemFontsGTK { - - public: - nsSystemFontsGTK(float aPixelsToTwips); - - const nsFont& GetDefaultFont() { return mDefaultFont; } - const nsFont& GetMenuFont() { return mMenuFont; } - const nsFont& GetFieldFont() { return mFieldFont; } - const nsFont& GetButtonFont() { return mButtonFont; } - - private: - nsresult GetSystemFontInfo(GtkWidget *aWidget, nsFont* aFont, - float aPixelsToTwips) const; - - /* - * The following system font constants exist: - * - * css2: http://www.w3.org/TR/REC-CSS2/fonts.html#x27 - * eSystemFont_Caption, eSystemFont_Icon, eSystemFont_Menu, - * eSystemFont_MessageBox, eSystemFont_SmallCaption, - * eSystemFont_StatusBar, - * // css3 - * eSystemFont_Window, eSystemFont_Document, - * eSystemFont_Workspace, eSystemFont_Desktop, - * eSystemFont_Info, eSystemFont_Dialog, - * eSystemFont_Button, eSystemFont_PullDownMenu, - * eSystemFont_List, eSystemFont_Field, - * // moz - * eSystemFont_Tooltips, eSystemFont_Widget - */ - nsFont mDefaultFont; - nsFont mButtonFont; - nsFont mFieldFont; - nsFont mMenuFont; -}; - - -nscoord nsDeviceContextGTK::mDpi = 96; -static nsSystemFontsGTK *gSystemFonts = nsnull; - -nsDeviceContextGTK::nsDeviceContextGTK() - : DeviceContextImpl() -{ - mTwipsToPixels = 1.0; - mPixelsToTwips = 1.0; - mDepth = 0 ; - mNumCells = 0; - - mDeviceWindow = nsnull; -} - -nsDeviceContextGTK::~nsDeviceContextGTK() -{ - nsresult rv; - nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) { - prefs->UnregisterCallback("layout.css.dpi", - prefChanged, (void *)this); - } -} - -/* static */ void nsDeviceContextGTK::Shutdown() -{ - if (gSystemFonts) { - delete gSystemFonts; - gSystemFonts = nsnull; - } -} - -NS_IMETHODIMP nsDeviceContextGTK::Init(nsNativeWidget aNativeWidget) -{ - GtkRequisition req; - GtkWidget *sb; - - // get the screen object and its width/height - // XXXRight now this will only get the primary monitor. - - if (!mScreenManager) - mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1"); - if (!mScreenManager) { - return NS_ERROR_FAILURE; - } - -#ifdef MOZ_WIDGET_GTK2 - - if (aNativeWidget) { - // can only be a gdk window - if (GDK_IS_WINDOW(aNativeWidget)) - mDeviceWindow = GDK_WINDOW(aNativeWidget); - else - NS_WARNING("unsupported native widget type!"); - } - -#endif - - nsCOMPtr screen; - mScreenManager->GetPrimaryScreen ( getter_AddRefs(screen) ); - if ( screen ) { - PRInt32 depth; - screen->GetPixelDepth ( &depth ); - mDepth = NS_STATIC_CAST ( PRUint32, depth ); - } - - static int initialized = 0; - PRInt32 prefVal = -1; - if (!initialized) { - initialized = 1; - - // Set prefVal the value of the preference - // "layout.css.dpi" - // or -1 if we can't get it. - // If it's negative, we pretend it's not set. - // If it's 0, it means force use of the operating system's logical - // resolution. - // If it's positive, we use it as the logical resolution - nsresult res; - - nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID, &res)); - if (NS_SUCCEEDED(res) && prefs) { - res = prefs->GetIntPref("layout.css.dpi", &prefVal); - if (NS_FAILED(res)) { - prefVal = -1; - } - prefs->RegisterCallback("layout.css.dpi", prefChanged, - (void *)this); - } - - SetDPI(prefVal); - } else { - SetDPI(mDpi); // to setup p2t and t2p - } - -#ifdef DEBUG - static PRBool once = PR_TRUE; - if (once) { - printf("GFX: dpi=%d t2p=%g p2t=%g depth=%d\n", mDpi, mTwipsToPixels, mPixelsToTwips,mDepth); - once = PR_FALSE; - } -#endif - - DeviceContextImpl::CommonInit(); - - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::CreateRenderingContext(nsIRenderingContext *&aContext) -{ -#ifdef NS_PRINT_PREVIEW - // Defer to Alt when there is one - if (mAltDC && ((mUseAltDC & kUseAltDCFor_CREATERC_PAINT) || (mUseAltDC & kUseAltDCFor_CREATERC_REFLOW))) { - return mAltDC->CreateRenderingContext(aContext); - } -#endif - - nsresult rv; - GtkWidget *w = (GtkWidget*)mWidget; - - // to call init for this, we need to have a valid nsDrawingSurfaceGTK created - nsIRenderingContext* pContext = new nsRenderingContextGTK(); - - if (nsnull != pContext) - { - NS_ADDREF(pContext); - - // create the nsDrawingSurfaceGTK - nsDrawingSurfaceGTK* surf = new nsDrawingSurfaceGTK(); - - if (surf && w) - { - GdkDrawable *gwin = nsnull; - GdkDrawable *win = nsnull; - // FIXME - if (GTK_IS_LAYOUT(w)) - gwin = (GdkDrawable*)GTK_LAYOUT(w)->bin_window; - else - gwin = (GdkDrawable*)(w)->window; - - // window might not be realized... ugh - if (gwin) - gdk_window_ref(gwin); - else { - win = gdk_pixmap_new(nsnull, - w->allocation.width, - w->allocation.height, - gdk_rgb_get_visual()->depth); -#ifdef MOZ_WIDGET_GTK2 - gdk_drawable_set_colormap(win, gdk_rgb_get_colormap()); -#endif - } - - GdkGC *gc = gdk_gc_new(win); - - // init the nsDrawingSurfaceGTK - rv = surf->Init(win,gc); - - if (NS_OK == rv) - // Init the nsRenderingContextGTK - rv = pContext->Init(this, surf); - } - else - rv = NS_ERROR_OUT_OF_MEMORY; - } - else - rv = NS_ERROR_OUT_OF_MEMORY; - - if (NS_OK != rv) - { - NS_IF_RELEASE(pContext); - } - - aContext = pContext; - - return rv; -} - -NS_IMETHODIMP nsDeviceContextGTK::CreateRenderingContextInstance(nsIRenderingContext *&aContext) -{ - nsCOMPtr renderingContext = new nsRenderingContextGTK(); - if (!renderingContext) - return NS_ERROR_OUT_OF_MEMORY; - - aContext = renderingContext; - NS_ADDREF(aContext); - - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::SupportsNativeWidgets(PRBool &aSupportsWidgets) -{ - //XXX it is very critical that this not lie!! MMP - // read the comments in the mac code for this - aSupportsWidgets = PR_TRUE; - - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::GetSystemFont(nsSystemFontID aID, nsFont *aFont) const -{ - nsresult status = NS_OK; - - if (!gSystemFonts) { - gSystemFonts = new nsSystemFontsGTK(mPixelsToTwips); - } - - switch (aID) { - case eSystemFont_Menu: // css2 - case eSystemFont_PullDownMenu: // css3 - *aFont = gSystemFonts->GetMenuFont(); - break; - - case eSystemFont_Field: // css3 - case eSystemFont_List: // css3 - *aFont = gSystemFonts->GetFieldFont(); - break; - - case eSystemFont_Button: // css3 - *aFont = gSystemFonts->GetButtonFont(); - break; - - case eSystemFont_Caption: // css2 - case eSystemFont_Icon: // css2 - case eSystemFont_MessageBox: // css2 - case eSystemFont_SmallCaption: // css2 - case eSystemFont_StatusBar: // css2 - case eSystemFont_Window: // css3 - case eSystemFont_Document: // css3 - case eSystemFont_Workspace: // css3 - case eSystemFont_Desktop: // css3 - case eSystemFont_Info: // css3 - case eSystemFont_Dialog: // css3 - case eSystemFont_Tooltips: // moz - case eSystemFont_Widget: // moz - *aFont = gSystemFonts->GetDefaultFont(); - break; - } - - return status; -} - -NS_IMETHODIMP nsDeviceContextGTK::CheckFontExistence(const nsString& aFontName) -{ - return NS_FontMetricsFamilyExists(this, aFontName); -} - -NS_IMETHODIMP nsDeviceContextGTK::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight) -{ -#ifdef NS_PRINT_PREVIEW - // Defer to Alt when there is one - if (mAltDC && (mUseAltDC & kUseAltDCFor_SURFACE_DIM)) { - return mAltDC->GetDeviceSurfaceDimensions(aWidth, aHeight); - } -#endif - - PRInt32 width = 0, height = 0; - - nsCOMPtr screen; - mScreenManager->GetPrimaryScreen(getter_AddRefs(screen)); - if (screen) { - PRInt32 x, y; - screen->GetRect(&x, &y, &width, &height); - } - - aWidth = NSToIntRound(float(width) * mDevUnitsToAppUnits); - aHeight = NSToIntRound(float(height) * mDevUnitsToAppUnits); - - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::GetRect(nsRect &aRect) -{ - // if we have an initialized widget for this device context, use it - // to try and get real screen coordinates. - if (mDeviceWindow) { - gint x, y, width, height, depth; - x = y = width = height = 0; - - gdk_window_get_geometry(mDeviceWindow, &x, &y, &width, &height, - &depth); - gdk_window_get_origin(mDeviceWindow, &x, &y); - - nsCOMPtr screen; - mScreenManager->ScreenForRect(x, y, width, height, getter_AddRefs(screen)); - screen->GetRect(&aRect.x, &aRect.y, &aRect.width, &aRect.height); - aRect.x = NSToIntRound(mDevUnitsToAppUnits * aRect.x); - aRect.y = NSToIntRound(mDevUnitsToAppUnits * aRect.y); - aRect.width = NSToIntRound(mDevUnitsToAppUnits * aRect.width); - aRect.height = NSToIntRound(mDevUnitsToAppUnits * aRect.height); - } - else { - PRInt32 width, height; - GetDeviceSurfaceDimensions(width, height); - aRect.x = 0; - aRect.y = 0; - aRect.width = width; - aRect.height = height; - } - return NS_OK; -} - - -NS_IMETHODIMP nsDeviceContextGTK::GetClientRect(nsRect &aRect) -{ - // if we have an initialized widget for this device context, use it - // to try and get real screen coordinates. - if (mDeviceWindow) { - gint x, y, width, height, depth; - x = y = width = height = 0; - - gdk_window_get_geometry(mDeviceWindow, &x, &y, &width, &height, - &depth); - gdk_window_get_origin(mDeviceWindow, &x, &y); - - nsCOMPtr screen; - mScreenManager->ScreenForRect(x, y, width, height, getter_AddRefs(screen)); - screen->GetAvailRect(&aRect.x, &aRect.y, &aRect.width, &aRect.height); - aRect.x = NSToIntRound(mDevUnitsToAppUnits * aRect.x); - aRect.y = NSToIntRound(mDevUnitsToAppUnits * aRect.y); - aRect.width = NSToIntRound(mDevUnitsToAppUnits * aRect.width); - aRect.height = NSToIntRound(mDevUnitsToAppUnits * aRect.height); - } - else { - PRInt32 width, height; - GetDeviceSurfaceDimensions(width, height); - aRect.x = 0; - aRect.y = 0; - aRect.width = width; - aRect.height = height; - } - - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::GetDeviceContextFor(nsIDeviceContextSpec *aDevice, - nsIDeviceContext *&aContext) -{ - nsresult rv; - -#if 0 - PrintMethod method; - - nsDeviceContextSpecGTK *spec = NS_STATIC_CAST(nsDeviceContextSpecGTK *, aDevice); - - rv = spec->GetPrintMethod(method); - if (NS_FAILED(rv)) - return rv; - -#endif -#ifdef USE_POSTSCRIPT -// if (method == pmPostScript) // PostScript - { - - // default/PS - static NS_DEFINE_CID(kCDeviceContextPS, NS_DEVICECONTEXTPS_CID); - - // Create a Postscript device context - nsCOMPtr dcps(do_CreateInstance(kCDeviceContextPS, &rv)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create PS Device context."); - if (NS_FAILED(rv)) - return NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE; - - rv = dcps->SetSpec(aDevice); - if (NS_FAILED(rv)) - return rv; - - rv = dcps->InitDeviceContextPS((nsIDeviceContext*)aContext, - (nsIDeviceContext*)this); - if (NS_FAILED(rv)) - return rv; - - rv = dcps->QueryInterface(NS_GET_IID(nsIDeviceContext), - (void **)&aContext); - return rv; - } - -#endif /* USE_POSTSCRIPT */ - NS_WARNING("no print module created."); - return NS_ERROR_UNEXPECTED; -} - -NS_IMETHODIMP nsDeviceContextGTK::BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage) -{ - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::EndDocument(void) -{ - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::AbortDocument(void) -{ - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::BeginPage(void) -{ - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::EndPage(void) -{ - return NS_OK; -} - -NS_IMETHODIMP nsDeviceContextGTK::GetDepth(PRUint32& aDepth) -{ - aDepth = mDepth; - return NS_OK; -} - -nsresult -nsDeviceContextGTK::SetDPI(PRInt32 aPrefDPI) -{ - PRInt32 OSVal = GetOSDPI(); - - if (aPrefDPI > 0) { - // If there's a valid pref value for the logical resolution, - // use it. - mDpi = aPrefDPI; - } else if ((aPrefDPI == 0) || (OSVal > 96)) { - // Either if the pref is 0 (force use of OS value) or the OS - // value is bigger than 96, use the OS value. - mDpi = OSVal; - } else { - // if we couldn't get the pref or it's negative, and the OS - // value is under 96ppi, then use 96. - mDpi = 96; - } - - int pt2t = 72; - - // make p2t a nice round number - this prevents rounding problems - mPixelsToTwips = float(NSToIntRound(float(NSIntPointsToTwips(pt2t)) / float(mDpi))); - mTwipsToPixels = 1.0f / mPixelsToTwips; - - // XXX need to reflow all documents - return NS_OK; -} - -static void DoClearCachedSystemFonts() -{ - //clear our cache of stored system fonts - if (gSystemFonts) { - delete gSystemFonts; - gSystemFonts = nsnull; - } -} - -NS_IMETHODIMP -nsDeviceContextGTK::ClearCachedSystemFonts() -{ - DoClearCachedSystemFonts(); - return NS_OK; -} - -int nsDeviceContextGTK::prefChanged(const char *aPref, void *aClosure) -{ - nsDeviceContextGTK *context = (nsDeviceContextGTK*)aClosure; - nsresult rv; - - if (nsCRT::strcmp(aPref, "layout.css.dpi")==0) { - PRInt32 dpi; - nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID, &rv)); - rv = prefs->GetIntPref(aPref, &dpi); - if (NS_SUCCEEDED(rv)) - context->SetDPI(dpi); - - // If this pref changes, we have to clear our cache of stored system - // fonts. - DoClearCachedSystemFonts(); - } - - return 0; -} - -#define DEFAULT_TWIP_FONT_SIZE 240 - -nsSystemFontsGTK::nsSystemFontsGTK(float aPixelsToTwips) - : mDefaultFont("sans-serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, - NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, - DEFAULT_TWIP_FONT_SIZE), - mButtonFont("sans-serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, - NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, - DEFAULT_TWIP_FONT_SIZE), - mFieldFont("sans-serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, - NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, - DEFAULT_TWIP_FONT_SIZE), - mMenuFont("sans-serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, - NS_FONT_WEIGHT_NORMAL, NS_FONT_DECORATION_NONE, - DEFAULT_TWIP_FONT_SIZE) -{ - /* - * Much of the widget creation code here is similar to the code in - * nsLookAndFeel::InitColors(). - */ - - // mDefaultFont - GtkWidget *label = gtk_label_new("M"); - GtkWidget *parent = gtk_fixed_new(); - GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); - - gtk_container_add(GTK_CONTAINER(parent), label); - gtk_container_add(GTK_CONTAINER(window), parent); - - gtk_widget_ensure_style(label); - - GetSystemFontInfo(label, &mDefaultFont, aPixelsToTwips); - - gtk_widget_destroy(window); // no unref, windows are different - - // mFieldFont - GtkWidget *entry = gtk_entry_new(); - parent = gtk_fixed_new(); - window = gtk_window_new(GTK_WINDOW_POPUP); - - gtk_container_add(GTK_CONTAINER(parent), entry); - gtk_container_add(GTK_CONTAINER(window), parent); - gtk_widget_ensure_style(entry); - - GetSystemFontInfo(entry, &mFieldFont, aPixelsToTwips); - - gtk_widget_destroy(window); // no unref, windows are different - - // mMenuFont - GtkWidget *accel_label = gtk_accel_label_new("M"); - GtkWidget *menuitem = gtk_menu_item_new(); - GtkWidget *menu = gtk_menu_new(); - gtk_object_ref(GTK_OBJECT(menu)); - gtk_object_sink(GTK_OBJECT(menu)); - - gtk_container_add(GTK_CONTAINER(menuitem), accel_label); - gtk_menu_append(GTK_MENU(menu), menuitem); - - gtk_widget_ensure_style(accel_label); - - GetSystemFontInfo(accel_label, &mMenuFont, aPixelsToTwips); - - gtk_widget_unref(menu); - - // mButtonFont - parent = gtk_fixed_new(); - GtkWidget *button = gtk_button_new(); - label = gtk_label_new("M"); - window = gtk_window_new(GTK_WINDOW_POPUP); - - gtk_container_add(GTK_CONTAINER(button), label); - gtk_container_add(GTK_CONTAINER(parent), button); - gtk_container_add(GTK_CONTAINER(window), parent); - - gtk_widget_ensure_style(label); - - GetSystemFontInfo(label, &mButtonFont, aPixelsToTwips); - - gtk_widget_destroy(window); // no unref, windows are different - -} - -#if 0 // debugging code to list the font properties -static void -ListFontProps(XFontStruct *aFont, Display *aDisplay) -{ - printf("\n\n"); - for (int i = 0, n = aFont->n_properties; i < n; ++i) { - XFontProp *prop = aFont->properties + i; - char *atomName = ::XGetAtomName(aDisplay, prop->name); - // 500 is just a guess - char *cardName = (prop->card32 > 0 && prop->card32 < 500) - ? ::XGetAtomName(aDisplay, prop->card32) - : 0; - printf("%s : %ld (%s)\n", atomName, prop->card32, cardName?cardName:""); - ::XFree(atomName); - if (cardName) - ::XFree(cardName); - } - printf("\n\n"); -} -#endif - -#if defined(MOZ_ENABLE_COREXFONTS) - -#define LOCATE_MINUS(pos, str) { \ - pos = str.FindChar('-'); \ - if (pos < 0) \ - return ; \ - } -#define NEXT_MINUS(pos, str) { \ - pos = str.FindChar('-', pos+1); \ - if (pos < 0) \ - return ; \ - } - -static void -AppendFontFFREName(nsString& aString, const char* aXLFDName) -{ - // convert fontname from XFLD to FFRE and append, ie. from - // -adobe-courier-medium-o-normal--14-140-75-75-m-90-iso8859-15 - // to - // adobe-courier-iso8859-15 - nsCAutoString nameStr(aXLFDName); - PRInt32 pos1, pos2; - // remove first '-' and everything before it. - LOCATE_MINUS(pos1, nameStr); - nameStr.Cut(0, pos1+1); - - // skip foundry and family name - LOCATE_MINUS(pos1, nameStr); - NEXT_MINUS(pos1, nameStr); - pos2 = pos1; - - // find '-' just before charset registry - for (PRInt32 i=0; i < 10; i++) { - NEXT_MINUS(pos2, nameStr); - } - - // remove everything in between - nameStr.Cut(pos1, pos2-pos1); - - aString.AppendWithConversion(nameStr.get()); -} -#endif /* MOZ_ENABLE_COREXFONTS */ - -#ifdef MOZ_WIDGET_GTK2 - -#ifdef MOZ_ENABLE_COREXFONTS -static void xlfd_from_pango_font_description(GtkWidget *aWidget, - const PangoFontDescription *aFontDesc, - nsString& aFontName); -#endif /* MOZ_ENABLE_COREXFONTS */ - -nsresult -nsSystemFontsGTK::GetSystemFontInfo(GtkWidget *aWidget, nsFont* aFont, - float aPixelsToTwips) const -{ - GtkSettings *settings = gtk_widget_get_settings(aWidget); - - aFont->style = NS_FONT_STYLE_NORMAL; - aFont->decorations = NS_FONT_DECORATION_NONE; - - gchar *fontname; - g_object_get(settings, "gtk-font-name", &fontname, NULL); - - PangoFontDescription *desc; - desc = pango_font_description_from_string(fontname); - - aFont->systemFont = PR_TRUE; - - g_free(fontname); - - aFont->name.Truncate(); -#ifdef MOZ_ENABLE_XFT - if (NS_IsXftEnabled()) { - aFont->name.Assign(PRUnichar('"')); - aFont->name.AppendWithConversion(pango_font_description_get_family(desc)); - aFont->name.Append(PRUnichar('"')); - } -#endif /* MOZ_ENABLE_XFT */ - -#ifdef MOZ_ENABLE_COREXFONTS - // if name already set by Xft, do nothing - if (!aFont->name.Length()) { - xlfd_from_pango_font_description(aWidget, desc, aFont->name); - } -#endif /* MOZ_ENABLE_COREXFONTS */ - aFont->weight = pango_font_description_get_weight(desc); - - float size = float(pango_font_description_get_size(desc) / PANGO_SCALE); -#ifdef MOZ_ENABLE_XFT - if (NS_IsXftEnabled()) { - PRInt32 dpi = GetXftDPI(); - if (dpi != 0) { - // pixels/inch * twips/pixel * inches/twip == 1, except it isn't, since - // our idea of dpi may be different from Xft's. - size *= float(dpi) * aPixelsToTwips * (1.0f/1440.0f); - } - } -#endif /* MOZ_ENABLE_XFT */ - aFont->size = NSFloatPointsToTwips(size); - - pango_font_description_free(desc); - - return NS_OK; -} -#endif /* MOZ_WIDGET_GTK2 */ - -#ifdef MOZ_WIDGET_GTK2 -/* static */ -PRInt32 -GetOSDPI(void) -{ - GtkSettings *settings = gtk_settings_get_default(); - - // first try to get the gtk2 dpi - gint dpi = 0; - - // See if there's a gtk-xft-dpi object on the settings object - note - // that we don't have to free the spec since it isn't addrefed - // before being returned. It's just part of an internal object. - // The gtk-xft-dpi setting is included in rh8 and might be included - // in later versions of gtk, so we conditionally check for it. - GParamSpec *spec; - spec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(settings)), - "gtk-xft-dpi"); - if (spec) { - g_object_get(G_OBJECT(settings), - "gtk-xft-dpi", &dpi, - NULL); - } - - if (dpi > 0) - return NSToCoordRound(dpi / 1024.0); - -#ifdef MOZ_ENABLE_XFT - // try to get it from xft - PRInt32 xftdpi = GetXftDPI(); - - if (xftdpi) - return xftdpi; -#endif /* MOZ_ENABLE_XFT */ - - // fall back to the physical resolution - float screenWidthIn = float(::gdk_screen_width_mm()) / 25.4f; - return NSToCoordRound(float(::gdk_screen_width()) / screenWidthIn); -} -#endif /* MOZ_WIDGET_GTK2 */ - -#ifdef MOZ_ENABLE_XFT -/* static */ -PRInt32 -GetXftDPI(void) -{ - char *val = XGetDefault(GDK_DISPLAY(), "Xft", "dpi"); - if (val) { - char *e; - double d = strtod(val, &e); - - if (e != val) - return NSToCoordRound(d); - } - - return 0; -} -#endif /* MOZ_ENABLE_XFT */ - -#if defined(MOZ_WIDGET_GTK2) && defined(MOZ_ENABLE_COREXFONTS) -// xlfd_from_pango_font_description copied from vte, which was -// written by nalin@redhat.com, and added some codes. -static void -xlfd_from_pango_font_description(GtkWidget *aWidget, - const PangoFontDescription *aFontDesc, - nsString& aFontName) -{ - char *spec; - PangoContext *context; - PangoFont *font; - PangoXSubfont *subfont_ids; - PangoFontMap *fontmap; - int *subfont_charsets, i, count = 0; - char *tmp, *subfont; - char *encodings[] = { - "ascii-0", - "big5-0", - "dos-437", - "dos-737", - "gb18030.2000-0", - "gb18030.2000-1", - "gb2312.1980-0", - "iso8859-1", - "iso8859-2", - "iso8859-3", - "iso8859-4", - "iso8859-5", - "iso8859-7", - "iso8859-8", - "iso8859-9", - "iso8859-10", - "iso8859-15", - "iso10646-0", - "iso10646-1", - "jisx0201.1976-0", - "jisx0208.1983-0", - "jisx0208.1990-0", - "jisx0208.1997-0", - "jisx0212.1990-0", - "jisx0213.2000-1", - "jisx0213.2000-2", - "koi8-r", - "koi8-u", - "koi8-ub", - "ksc5601.1987-0", - "ksc5601.1992-3", - "tis620-0", - "iso8859-13", - "microsoft-cp1251" - "misc-fontspecific", - }; -#if XlibSpecificationRelease >= 6 - XOM xom; -#endif - if (!aFontDesc) { - return; - } - - context = gtk_widget_get_pango_context(GTK_WIDGET(aWidget)); - - pango_context_set_language (context, gtk_get_default_language ()); - fontmap = pango_x_font_map_for_display(GDK_DISPLAY()); - - if (!fontmap) { - return; - } - - font = pango_font_map_load_font(fontmap, context, aFontDesc); - if (!font) { - return; - } - -#if XlibSpecificationRelease >= 6 - xom = XOpenOM (GDK_DISPLAY(), NULL, NULL, NULL); - if (xom) { - XOMCharSetList cslist; - int n_encodings = 0; - cslist.charset_count = 0; - XGetOMValues (xom, - XNRequiredCharSet, &cslist, - NULL); - n_encodings = cslist.charset_count; - if (n_encodings) { - char **xom_encodings = (char**) g_malloc (sizeof(char*) * n_encodings); - - for (i = 0; i < n_encodings; i++) { - xom_encodings[i] = g_ascii_strdown (cslist.charset_list[i], -1); - } - count = pango_x_list_subfonts(font, xom_encodings, n_encodings, - &subfont_ids, &subfont_charsets); - - for(i = 0; i < n_encodings; i++) { - g_free (xom_encodings[i]); - } - g_free (xom_encodings); - } - XCloseOM (xom); - } -#endif - if (count == 0) { - count = pango_x_list_subfonts(font, encodings, G_N_ELEMENTS(encodings), - &subfont_ids, &subfont_charsets); - } - - for (i = 0; i < count; i++) { - subfont = pango_x_font_subfont_xlfd(font, subfont_ids[i]); - AppendFontFFREName(aFontName, subfont); - g_free(subfont); - aFontName.Append(PRUnichar(',')); - } - - spec = pango_font_description_to_string(aFontDesc); - - if (subfont_ids != NULL) { - g_free(subfont_ids); - } - if (subfont_charsets != NULL) { - g_free(subfont_charsets); - } - g_free(spec); - g_object_unref(font); -} -#endif /* MOZ_WIDGET_GTK2 && MOZ_ENABLE_COREXFONTS */ diff --git a/gfx/src/gtk/nsDeviceContextGTK.h b/gfx/src/gtk/nsDeviceContextGTK.h deleted file mode 100644 index 11388659400a..000000000000 --- a/gfx/src/gtk/nsDeviceContextGTK.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsDeviceContextGTK_h___ -#define nsDeviceContextGTK_h___ - -#include "nsDeviceContext.h" -#include "nsUnitConversion.h" -#include "nsIWidget.h" -#include "nsIView.h" -#include "nsIRenderingContext.h" - -#include "nsRenderingContextGTK.h" -#include "nsIScreenManager.h" - -class nsDeviceContextGTK : public DeviceContextImpl -{ -public: - nsDeviceContextGTK(); - virtual ~nsDeviceContextGTK(); - - static void Shutdown(); // to be called from module destructor - - NS_IMETHOD Init(nsNativeWidget aNativeWidget); - - NS_IMETHOD CreateRenderingContext(nsIRenderingContext *&aContext); - NS_IMETHOD CreateRenderingContext(nsIView *aView, nsIRenderingContext *&aContext) {return (DeviceContextImpl::CreateRenderingContext(aView,aContext));} - NS_IMETHOD CreateRenderingContext(nsIWidget *aWidget, nsIRenderingContext *&aContext) {return (DeviceContextImpl::CreateRenderingContext(aWidget,aContext));} - NS_IMETHOD CreateRenderingContext(nsIDrawingSurface* aSurface, nsIRenderingContext *&aContext) {return (DeviceContextImpl::CreateRenderingContext(aSurface, aContext));} - NS_IMETHOD CreateRenderingContextInstance(nsIRenderingContext *&aContext); - - NS_IMETHOD SupportsNativeWidgets(PRBool &aSupportsWidgets); - - NS_IMETHOD GetSystemFont(nsSystemFontID anID, nsFont *aFont) const; - - NS_IMETHOD CheckFontExistence(const nsString& aFontName); - - NS_IMETHOD GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight); - NS_IMETHOD GetClientRect(nsRect &aRect); - NS_IMETHOD GetRect(nsRect &aRect); - - NS_IMETHOD GetDeviceContextFor(nsIDeviceContextSpec *aDevice, - nsIDeviceContext *&aContext); - - NS_IMETHOD BeginDocument(PRUnichar * aTitle, PRUnichar* aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage); - NS_IMETHOD EndDocument(void); - NS_IMETHOD AbortDocument(void); - - NS_IMETHOD BeginPage(void); - NS_IMETHOD EndPage(void); - - NS_IMETHOD GetDepth(PRUint32& aDepth); - - NS_IMETHOD ClearCachedSystemFonts(); - - static int prefChanged(const char *aPref, void *aClosure); - -protected: - nsresult SetDPI(PRInt32 aPrefDPI); - -private: - PRUint32 mDepth; - PRBool mWriteable; - PRUint32 mNumCells; - static nscoord mDpi; - - float mWidthFloat; - float mHeightFloat; - PRInt32 mWidth; - PRInt32 mHeight; - GdkWindow *mDeviceWindow; - - nsCOMPtr mScreenManager; - - nsresult GetSystemFontInfo(GdkFont* iFont, nsSystemFontID anID, nsFont* aFont) const; -}; - -// used by several files - -#define NS_TO_GDK_RGB(ns) \ - ((ns & 0xff) << 16 | (ns & 0xff00) | ((ns >> 16) & 0xff)) -#define GDK_COLOR_TO_NS_RGB(c) \ - ((nscolor) NS_RGB(c.red, c.green, c.blue)) - - -#endif /* nsDeviceContextGTK_h___ */ - diff --git a/gfx/src/gtk/nsDrawingSurfaceGTK.cpp b/gfx/src/gtk/nsDrawingSurfaceGTK.cpp deleted file mode 100644 index a81b45f7a4dc..000000000000 --- a/gfx/src/gtk/nsDrawingSurfaceGTK.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#include -#include -#include "nsDrawingSurfaceGTK.h" - -NS_IMPL_ISUPPORTS1(nsDrawingSurfaceGTK, nsIDrawingSurface) - -//#define CHEAP_PERFORMANCE_MEASUREMENT - -#ifdef CHEAP_PERFORMANCE_MEASUREMENT -static PRTime mLockTime, mUnlockTime; -#endif - -#ifdef MOZ_ENABLE_XFT -#include -#endif - -nsDrawingSurfaceGTK :: nsDrawingSurfaceGTK() -{ - GdkVisual *v; - - mPixmap = nsnull; - mGC = nsnull; - mDepth = 0; - mWidth = 0; - mHeight = 0; - mFlags = 0; - - mImage = nsnull; - mLockWidth = 0; - mLockHeight = 0; - mLockFlags = 0; - mLockX = 0; - mLockY = 0; - mLocked = PR_FALSE; - - v = ::gdk_rgb_get_visual(); - - mPixFormat.mRedMask = v->red_mask; - mPixFormat.mGreenMask = v->green_mask; - mPixFormat.mBlueMask = v->blue_mask; - // FIXME - mPixFormat.mAlphaMask = 0; - - mPixFormat.mRedCount = ConvertMaskToCount(v->red_mask); - mPixFormat.mGreenCount = ConvertMaskToCount(v->green_mask); - mPixFormat.mBlueCount = ConvertMaskToCount(v->blue_mask);; - - - mPixFormat.mRedShift = v->red_shift; - mPixFormat.mGreenShift = v->green_shift; - mPixFormat.mBlueShift = v->blue_shift; - // FIXME - mPixFormat.mAlphaShift = 0; - - mDepth = v->depth; - -#ifdef MOZ_ENABLE_XFT - mXftDraw = nsnull; -#endif -} - -nsDrawingSurfaceGTK :: ~nsDrawingSurfaceGTK() -{ - if (mPixmap) - ::gdk_pixmap_unref(mPixmap); - - if (mImage) - ::gdk_image_destroy(mImage); - - if (mGC) - gdk_gc_unref(mGC); - -#ifdef MOZ_ENABLE_XFT - if (mXftDraw) - XftDrawDestroy(mXftDraw); -#endif -} - -/** - * Lock a rect of a drawing surface and return a - * pointer to the upper left hand corner of the - * bitmap. - * @param aX x position of subrect of bitmap - * @param aY y position of subrect of bitmap - * @param aWidth width of subrect of bitmap - * @param aHeight height of subrect of bitmap - * @param aBits out parameter for upper left hand - * corner of bitmap - * @param aStride out parameter for number of bytes - * to add to aBits to go from scanline to scanline - * @param aWidthBytes out parameter for number of - * bytes per line in aBits to process aWidth pixels - * @return error status - * - **/ -NS_IMETHODIMP nsDrawingSurfaceGTK :: Lock(PRInt32 aX, PRInt32 aY, - PRUint32 aWidth, PRUint32 aHeight, - void **aBits, PRInt32 *aStride, - PRInt32 *aWidthBytes, PRUint32 aFlags) -{ -#ifdef CHEAP_PERFORMANCE_MEASUREMENT - mLockTime = PR_Now(); - // MOZ_TIMER_RESET(mLockTime); - // MOZ_TIMER_START(mLockTime); -#endif - -#if 0 - g_print("nsDrawingSurfaceGTK::Lock() called\n" \ - " aX = %i, aY = %i,\n" \ - " aWidth = %i, aHeight = %i,\n" \ - " aBits, aStride, aWidthBytes,\n" \ - " aFlags = %i\n", aX, aY, aWidth, aHeight, aFlags); -#endif - - if (mLocked) - { - NS_ASSERTION(0, "nested lock attempt"); - return NS_ERROR_FAILURE; - } - mLocked = PR_TRUE; - - mLockX = aX; - mLockY = aY; - mLockWidth = aWidth; - mLockHeight = aHeight; - mLockFlags = aFlags; - - // Obtain an ximage from the pixmap. - mImage = ::gdk_image_get(mPixmap, mLockX, mLockY, mLockWidth, mLockHeight); - - if (!mImage) { - mLocked = PR_FALSE; - return NS_ERROR_FAILURE; - } - - *aBits = GDK_IMAGE_XIMAGE(mImage)->data; - - // Use GDK_IMAGE_XIMAGE(mImage)->bits_per_pixel instead of mImage->bpp - // since, although bpp is documented as *bytes* per pixel, GDK1 sometimes - // set it as *bits* per pixel. - *aWidthBytes = aWidth * ((GDK_IMAGE_XIMAGE(mImage)->bits_per_pixel + 7) / 8); - *aStride = GDK_IMAGE_XIMAGE(mImage)->bytes_per_line; - -#ifdef CHEAP_PERFORMANCE_MEASUREMENT - // MOZ_TIMER_STOP(mLockTime); - // MOZ_TIMER_LOG(("Time taken to lock: ")); - // MOZ_TIMER_PRINT(mLockTime); - printf("Time taken to lock: %d\n", PR_Now() - mLockTime); -#endif - - return NS_OK; -} - -NS_IMETHODIMP nsDrawingSurfaceGTK :: Unlock(void) -{ - -#ifdef CHEAP_PERFORMANCE_MEASUREMENT - mUnlockTime = PR_Now(); -#endif - - // g_print("nsDrawingSurfaceGTK::UnLock() called\n"); - if (!mLocked) - { - NS_ASSERTION(0, "attempting to unlock an DS that isn't locked"); - return NS_ERROR_FAILURE; - } - - // If the lock was not read only, put the bits back on the pixmap - if (!(mLockFlags & NS_LOCK_SURFACE_READ_ONLY)) - { -#if 0 - g_print("%p gdk_draw_image(pixmap=%p,lockx=%d,locky=%d,lockw=%d,lockh=%d)\n", - this, - mPixmap, - mLockX, mLockY, - mLockWidth, mLockHeight); -#endif - - gdk_draw_image(mPixmap, - mGC, - mImage, - 0, 0, - mLockX, mLockY, - mLockWidth, mLockHeight); - } - - if (mImage) - ::gdk_image_destroy(mImage); - mImage = nsnull; - - mLocked = PR_FALSE; - - -#ifdef CHEAP_PERFORMANCE_MEASUREMENT - printf("Time taken to unlock: %d\n", PR_Now() - mUnlockTime); -#endif - - return NS_OK; -} - -NS_IMETHODIMP nsDrawingSurfaceGTK :: GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight) -{ - *aWidth = mWidth; - *aHeight = mHeight; - - return NS_OK; -} - -NS_IMETHODIMP nsDrawingSurfaceGTK :: IsOffscreen(PRBool *aOffScreen) -{ - *aOffScreen = mIsOffscreen; - return NS_OK; -} - -NS_IMETHODIMP nsDrawingSurfaceGTK :: IsPixelAddressable(PRBool *aAddressable) -{ -// FIXME - *aAddressable = PR_FALSE; - return NS_OK; -} - -NS_IMETHODIMP nsDrawingSurfaceGTK :: GetPixelFormat(nsPixelFormat *aFormat) -{ - *aFormat = mPixFormat; - - return NS_OK; -} - -nsresult nsDrawingSurfaceGTK :: Init(GdkDrawable *aDrawable, GdkGC *aGC) -{ - if (mGC) - gdk_gc_unref(mGC); - - mGC = gdk_gc_ref(aGC); - mPixmap = aDrawable; - -#ifdef MOZ_WIDGET_GTK2 - gint width = 0; - gint height = 0; - gdk_drawable_get_size(aDrawable, &width, &height); - mWidth = width; - mHeight = height; -#endif /* MOZ_WIDGET_GTK2 */ - - // XXX was i smoking crack when i wrote this comment? - // this is definatly going to be on the screen, as it will be the window of a - // widget or something. - mIsOffscreen = PR_FALSE; - - if (mImage) - gdk_image_destroy(mImage); - mImage = nsnull; - - g_return_val_if_fail(mPixmap != nsnull, NS_ERROR_FAILURE); - - return NS_OK; -} - -nsresult nsDrawingSurfaceGTK :: Init(GdkGC *aGC, PRUint32 aWidth, - PRUint32 aHeight, PRUint32 aFlags) -{ - // ::g_return_val_if_fail (aGC != nsnull, NS_ERROR_FAILURE); - // ::g_return_val_if_fail ((aWidth > 0) && (aHeight > 0), NS_ERROR_FAILURE); - if (mGC) - gdk_gc_unref(mGC); - - mGC = gdk_gc_ref(aGC); - mWidth = aWidth; - mHeight = aHeight; - mFlags = aFlags; - - // we can draw on this offscreen because it has no parent - mIsOffscreen = PR_TRUE; - - mPixmap = ::gdk_pixmap_new(nsnull, mWidth, mHeight, mDepth); -#ifdef MOZ_WIDGET_GTK2 - gdk_drawable_set_colormap(GDK_DRAWABLE(mPixmap), gdk_rgb_get_colormap()); -#endif - - if (mImage) - gdk_image_destroy(mImage); - mImage = nsnull; - - return mPixmap ? NS_OK : NS_ERROR_FAILURE; -} - -#ifdef MOZ_ENABLE_XFT -XftDraw *nsDrawingSurfaceGTK :: GetXftDraw(void) -{ - if (!mXftDraw) { - mXftDraw = XftDrawCreate(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(mPixmap), - GDK_VISUAL_XVISUAL(::gdk_rgb_get_visual()), - GDK_COLORMAP_XCOLORMAP(::gdk_rgb_get_cmap())); - } - - return mXftDraw; -} - -void nsDrawingSurfaceGTK :: GetLastXftClip(nsIRegion **aLastRegion) -{ - *aLastRegion = mLastXftClip.get(); - NS_IF_ADDREF(*aLastRegion); -} - -void nsDrawingSurfaceGTK :: SetLastXftClip(nsIRegion *aLastRegion) -{ - mLastXftClip = aLastRegion; -} - -#endif /* MOZ_ENABLE_XFT */ - -/* inline */ -PRUint8 -nsDrawingSurfaceGTK::ConvertMaskToCount(unsigned long val) -{ - PRUint8 retval = 0; - PRUint8 cur_bit = 0; - // walk through the number, incrementing the value if - // the bit in question is set. - while (cur_bit < (sizeof(unsigned long) * 8)) { - if ((val >> cur_bit) & 0x1) { - retval++; - } - cur_bit++; - } - return retval; -} diff --git a/gfx/src/gtk/nsDrawingSurfaceGTK.h b/gfx/src/gtk/nsDrawingSurfaceGTK.h deleted file mode 100644 index 859cd7d443b3..000000000000 --- a/gfx/src/gtk/nsDrawingSurfaceGTK.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsDrawingSurfaceGTK_h___ -#define nsDrawingSurfaceGTK_h___ - -#include "nsIDrawingSurface.h" - -#include "nsTimer.h" -#include "nsIRegion.h" -#include "nsCOMPtr.h" - -#include - -#ifdef MOZ_ENABLE_XFT -typedef struct _XftDraw XftDraw; -#endif - -class nsDrawingSurfaceGTK : public nsIDrawingSurface -{ -public: - nsDrawingSurfaceGTK(); - virtual ~nsDrawingSurfaceGTK(); - - /** - * Initialize a drawing surface using a windows DC. - * aDC is "owned" by the drawing surface until the drawing - * surface is destroyed. - * @param aDC HDC to initialize drawing surface with - * @return error status - **/ - - nsresult Init(GdkDrawable *aDrawable, GdkGC *aGC); - - /** - * Initialize an offscreen drawing surface using a - * windows DC. aDC is not "owned" by this drawing surface, instead - * it is used to create a drawing surface compatible - * with aDC. if width or height are less than zero, aDC will - * be created with no offscreen bitmap installed. - * @param aDC HDC to initialize drawing surface with - * @param aWidth width of drawing surface - * @param aHeight height of drawing surface - * @param aFlags flags used to control type of drawing - * surface created - * @return error status - **/ - - nsresult Init(GdkGC *aGC, PRUint32 aWidth, PRUint32 aHeight, - PRUint32 aFlags); - - NS_DECL_ISUPPORTS - - //nsIDrawingSurface interface - - NS_IMETHOD Lock(PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight, - void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes, - PRUint32 aFlags); - NS_IMETHOD Unlock(void); - NS_IMETHOD GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight); - NS_IMETHOD IsOffscreen(PRBool *aOffScreen); - NS_IMETHOD IsPixelAddressable(PRBool *aAddressable); - NS_IMETHOD GetPixelFormat(nsPixelFormat *aFormat); - -/* below are utility functions used mostly for nsRenderingContext and nsImage - * to plug into gdk_* functions for drawing. You should not set a pointer - * that might hang around with the return from these. instead use the ones - * above. pav - */ - GdkDrawable *GetDrawable(void) { return mPixmap; } - - void GetSize(PRUint32 *aWidth, PRUint32 *aHeight) { *aWidth = mWidth; *aHeight = mHeight; } - - PRInt32 GetDepth() { return mDepth; } - -#ifdef MOZ_ENABLE_XFT - XftDraw *GetXftDraw (void); - void GetLastXftClip (nsIRegion **aLastRegion); - void SetLastXftClip (nsIRegion *aLastRegion); -#endif /* MOZ_ENABLE_XFT */ - -protected: - inline PRUint8 ConvertMaskToCount(unsigned long val); - -private: - /* general */ - GdkPixmap *mPixmap; - GdkGC *mGC; - gint mDepth; - nsPixelFormat mPixFormat; - PRUint32 mWidth; - PRUint32 mHeight; - PRUint32 mFlags; - PRBool mIsOffscreen; - - /* for locks */ - GdkImage *mImage; - PRInt32 mLockX; - PRInt32 mLockY; - PRUint32 mLockWidth; - PRUint32 mLockHeight; - PRUint32 mLockFlags; - PRBool mLocked; - -#ifdef MOZ_ENABLE_XFT - XftDraw *mXftDraw; - nsCOMPtr mLastXftClip; -#endif - - // MOZ_TIMER_DECLARE(mLockTime) - // MOZ_TIMER_DECLARE(mUnlockTime) -}; - -#endif diff --git a/gfx/src/gtk/nsFontMetricsGTK.cpp b/gfx/src/gtk/nsFontMetricsGTK.cpp deleted file mode 100644 index e8619e88ebe8..000000000000 --- a/gfx/src/gtk/nsFontMetricsGTK.cpp +++ /dev/null @@ -1,6793 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Pierre Phaneuf - * Roland Mainz - * Brian Stell - * Morten Nilsen - * Jungshik Shin - * IBM Corporation - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#define ENABLE_X_FONT_BANNING 1 - -#include -#include "gfx-config.h" -#include "nscore.h" -#include "nsQuickSort.h" -#include "nsFontMetricsGTK.h" -#include "nsIServiceManager.h" -#include "nsICharsetConverterManager.h" -#include "nsILanguageAtomService.h" -#include "nsISaveAsCharset.h" -#include "nsIPref.h" -#include "nsCOMPtr.h" -#include "nsPrintfCString.h" -#include "nspr.h" -#include "nsHashtable.h" -#include "nsReadableUtils.h" -#include "nsAString.h" -#include "nsXPIDLString.h" -#include "nsFontDebug.h" -#include "nsCharTraits.h" -#ifdef MOZ_ENABLE_FREETYPE2 -#include "nsFT2FontNode.h" -#include "nsFontFreeType.h" -#endif -#include "nsXFontNormal.h" -#include "nsX11AlphaBlend.h" -#include "nsXFontAAScaledBitmap.h" -#include "nsUnicharUtils.h" -#ifdef ENABLE_X_FONT_BANNING -#include -#endif /* ENABLE_X_FONT_BANNING */ - -#include -#include - -#ifdef PR_LOGGING -static PRLogModuleInfo * FontMetricsGTKLM = PR_NewLogModule("FontMetricsGTK"); -#endif /* PR_LOGGING */ - -#ifdef ENABLE_X_FONT_BANNING -/* Not all platforms may have REG_OK */ -#ifndef REG_OK -#define REG_OK (0) -#endif /* !REG_OK */ -#endif /* ENABLE_X_FONT_BANNING */ - -#undef USER_DEFINED -#define USER_DEFINED "x-user-def" - -// This is the scaling factor that we keep fonts limited to against -// the display size. If a pixel size is requested that is more than -// this factor larger than the height of the display, it's clamped to -// that value instead of the requested size. -#define FONT_MAX_FONT_SCALE 2 - -#undef NOISY_FONTS -#undef REALLY_NOISY_FONTS - -#ifndef MOZ_ENABLE_FREETYPE2 -static PRUint32 gFontDebug = 0 | NS_FONT_DEBUG_FONT_SCAN; -#endif - -struct nsFontCharSetMap; -struct nsFontFamilyName; -struct nsFontPropertyName; -struct nsFontStyle; -struct nsFontWeight; -struct nsFontLangGroup; - -struct nsFontCharSetInfo -{ - const char* mCharSet; - nsFontCharSetConverter Convert; - PRUint8 mSpecialUnderline; -#ifdef MOZ_ENABLE_FREETYPE2 - PRInt32 mCodeRange1Bits; - PRInt32 mCodeRange2Bits; -#endif - PRUint16* mCCMap; - nsIUnicodeEncoder* mConverter; - nsIAtom* mLangGroup; - PRBool mInitedSizeInfo; - PRInt32 mOutlineScaleMin; - PRInt32 mAABitmapScaleMin; - double mAABitmapOversize; - double mAABitmapUndersize; - PRBool mAABitmapScaleAlways; - PRInt32 mBitmapScaleMin; - double mBitmapOversize; - double mBitmapUndersize; -}; - -struct nsFontFamily -{ - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - nsFontNodeArray mNodes; -}; - -struct nsFontFamilyName -{ - const char* mName; - const char* mXName; -}; - -struct nsFontPropertyName -{ - const char* mName; - int mValue; -}; - -static void SetCharsetLangGroup(nsFontCharSetInfo* aCharSetInfo); - -static int gFontMetricsGTKCount = 0; -static int gInitialized = 0; -static PRBool gForceOutlineScaledFonts = PR_FALSE; -static PRBool gAllowDoubleByteSpecialChars = PR_TRUE; - -// XXX many of these statics need to be freed at shutdown time - -static nsIPref* gPref = nsnull; -static float gDevScale = 0.0f; /* Scaler value from |GetCanonicalPixelScale()| */ -static PRBool gScaleBitmapFontsWithDevScale = PR_FALSE; -static nsICharsetConverterManager* gCharSetManager = nsnull; -static nsIUnicodeEncoder* gUserDefinedConverter = nsnull; - -static nsHashtable* gAliases = nsnull; -static nsHashtable* gCharSetMaps = nsnull; -static nsHashtable* gFamilies = nsnull; -static nsHashtable* gFFRENodes = nsnull; -static nsHashtable* gAFRENodes = nsnull; -// gCachedFFRESearches holds the "already looked up" -// FFRE (Foundry Family Registry Encoding) font searches -static nsHashtable* gCachedFFRESearches = nsnull; -static nsHashtable* gSpecialCharSets = nsnull; -static nsHashtable* gStretches = nsnull; -static nsHashtable* gWeights = nsnull; -nsISaveAsCharset* gFontSubConverter = nsnull; - -static nsFontNodeArray* gGlobalList = nsnull; - -static nsIAtom* gUnicode = nsnull; -static nsIAtom* gUserDefined = nsnull; -static nsIAtom* gZHTW = nsnull; -static nsIAtom* gZHHK = nsnull; -static nsIAtom* gZHTWHK = nsnull; // for fonts common to zh-TW and zh-HK -static nsIAtom* gUsersLocale = nsnull; -static nsIAtom* gWesternLocale = nsnull; - -// Controls for Outline Scaled Fonts (okay looking) - -static PRInt32 gOutlineScaleMinimum = 6; -// Controls for Anti-Aliased Scaled Bitmaps (okay looking) -static PRBool gAABitmapScaleEnabled = PR_TRUE; -static PRBool gAABitmapScaleAlways = PR_FALSE; -static PRInt32 gAABitmapScaleMinimum = 6; -static double gAABitmapOversize = 1.1; -static double gAABitmapUndersize = 0.9; - -// Controls for (regular) Scaled Bitmaps (very ugly) -static PRInt32 gBitmapScaleMinimum = 10; -static double gBitmapOversize = 1.2; -static double gBitmapUndersize = 0.8; - -#ifdef ENABLE_X_FONT_BANNING -static regex_t *gFontRejectRegEx = nsnull, - *gFontAcceptRegEx = nsnull; -#endif /* ENABLE_X_FONT_BANNING */ - -static gint SingleByteConvert(nsFontCharSetInfo* aSelf, XFontStruct* aFont, - const PRUnichar* aSrcBuf, PRInt32 aSrcLen, char* aDestBuf, PRInt32 aDestLen); -static gint DoubleByteConvert(nsFontCharSetInfo* aSelf, XFontStruct* aFont, - const PRUnichar* aSrcBuf, PRInt32 aSrcLen, char* aDestBuf, PRInt32 aDestLen); -static gint ISO10646Convert(nsFontCharSetInfo* aSelf, XFontStruct* aFont, - const PRUnichar* aSrcBuf, PRInt32 aSrcLen, char* aDestBuf, PRInt32 aDestLen); - -static nsFontCharSetInfo Unknown = { nsnull }; -static nsFontCharSetInfo Special = { nsnull }; - -#ifdef MOZ_ENABLE_FREETYPE2 -static nsFontCharSetInfo USASCII = - { "us-ascii", SingleByteConvert, 0, - TT_OS2_CPR1_LATIN1 | TT_OS2_CPR1_MAC_ROMAN, - TT_OS2_CPR2_CA_FRENCH | TT_OS2_CPR2_PORTUGESE - | TT_OS2_CPR2_WE_LATIN1 | TT_OS2_CPR2_US }; -static nsFontCharSetInfo ISO88591 = - { "ISO-8859-1", SingleByteConvert, 0, - TT_OS2_CPR1_LATIN1 | TT_OS2_CPR1_MAC_ROMAN, - TT_OS2_CPR2_CA_FRENCH | TT_OS2_CPR2_PORTUGESE - | TT_OS2_CPR2_WE_LATIN1 | TT_OS2_CPR2_US }; -static nsFontCharSetInfo ISO88592 = - { "ISO-8859-2", SingleByteConvert, 0, - TT_OS2_CPR1_LATIN2, TT_OS2_CPR2_LATIN2 }; -static nsFontCharSetInfo ISO88593 = - { "ISO-8859-3", SingleByteConvert, 0, - TT_OS2_CPR1_TURKISH, TT_OS2_CPR2_TURKISH }; -static nsFontCharSetInfo ISO88594 = - { "ISO-8859-4", SingleByteConvert, 0, - TT_OS2_CPR1_BALTIC, TT_OS2_CPR2_BALTIC }; -static nsFontCharSetInfo ISO88595 = - { "ISO-8859-5", SingleByteConvert, 0, - TT_OS2_CPR1_CYRILLIC, TT_OS2_CPR2_RUSSIAN | TT_OS2_CPR2_CYRILLIC }; -static nsFontCharSetInfo ISO88596 = - { "ISO-8859-6", SingleByteConvert, 0, - TT_OS2_CPR1_ARABIC, TT_OS2_CPR2_ARABIC | TT_OS2_CPR2_ARABIC_708 }; -static nsFontCharSetInfo ISO885968x = - { "x-iso-8859-6-8-x", SingleByteConvert, 0, - TT_OS2_CPR1_ARABIC, TT_OS2_CPR2_ARABIC | TT_OS2_CPR2_ARABIC_708 }; -static nsFontCharSetInfo ISO8859616 = - { "x-iso-8859-6-16", SingleByteConvert, 0, - TT_OS2_CPR1_ARABIC, TT_OS2_CPR2_ARABIC | TT_OS2_CPR2_ARABIC_708 }; -static nsFontCharSetInfo IBM1046 = - { "x-IBM1046", SingleByteConvert, 0, - TT_OS2_CPR1_ARABIC, TT_OS2_CPR2_ARABIC | TT_OS2_CPR2_ARABIC_708 }; -static nsFontCharSetInfo ISO88597 = - { "ISO-8859-7", SingleByteConvert, 0, - TT_OS2_CPR1_GREEK, TT_OS2_CPR2_GREEK | TT_OS2_CPR2_GREEK_437G }; -static nsFontCharSetInfo ISO88598 = - { "ISO-8859-8", SingleByteConvert, 0, - TT_OS2_CPR1_HEBREW, TT_OS2_CPR2_HEBREW }; -// change from -// { "ISO-8859-8", SingleByteConvertReverse, 0, 0, 0 }; -// untill we fix the layout and ensure we only call this with pure RTL text -static nsFontCharSetInfo ISO88599 = - { "ISO-8859-9", SingleByteConvert, 0, - TT_OS2_CPR1_TURKISH, TT_OS2_CPR2_TURKISH }; -// no support for iso-8859-10 (Nordic/Icelandic) currently -// static nsFontCharSetInfo ISO885910 = -// { "ISO-8859-10", SingleByteConvert, 0, -// 0, TT_OS2_CPR2_NORDIC | TT_OS2_CPR2_ICELANDIC }; -// no support for iso-8859-12 (Vietnamese) currently -// static nsFontCharSetInfo ISO885912 = -// { "ISO-8859-12", SingleByteConvert, 0, -// TT_OS2_CPR1_VIETNAMESE, 0 }; -static nsFontCharSetInfo ISO885913 = - { "ISO-8859-13", SingleByteConvert, 0, - TT_OS2_CPR1_BALTIC, TT_OS2_CPR2_BALTIC }; -static nsFontCharSetInfo ISO885915 = - { "ISO-8859-15", SingleByteConvert, 0, - TT_OS2_CPR1_LATIN2, TT_OS2_CPR2_LATIN2 }; -static nsFontCharSetInfo JISX0201 = - { "jis_0201", SingleByteConvert, 1, - TT_OS2_CPR1_JAPANESE, 0 }; -static nsFontCharSetInfo KOI8R = - { "KOI8-R", SingleByteConvert, 0, - TT_OS2_CPR1_CYRILLIC, TT_OS2_CPR2_RUSSIAN | TT_OS2_CPR2_CYRILLIC }; -static nsFontCharSetInfo KOI8U = - { "KOI8-U", SingleByteConvert, 0, - TT_OS2_CPR1_CYRILLIC, TT_OS2_CPR2_RUSSIAN | TT_OS2_CPR2_CYRILLIC }; -static nsFontCharSetInfo TIS6202 = -/* Added to support thai context sensitive shaping if - * CTL extension is is in force */ -#ifdef SUNCTL - { "tis620-2", SingleByteConvert, 0, - TT_OS2_CPR1_THAI, 0 }; -#else - { "windows-874", SingleByteConvert, 0, - TT_OS2_CPR1_THAI, 0 }; -#endif /* SUNCTL */ -static nsFontCharSetInfo TIS620 = - { "TIS-620", SingleByteConvert, 0, - TT_OS2_CPR1_THAI, 0 }; -static nsFontCharSetInfo ISO885911 = - { "ISO-8859-11", SingleByteConvert, 0, - TT_OS2_CPR1_THAI, 0 }; -static nsFontCharSetInfo Big5 = - { "x-x-big5", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -// a kludge to distinguish zh-TW only fonts in Big5 (such as hpbig5-) -// from zh-TW/zh-HK common fonts in Big5 (such as big5-1) -static nsFontCharSetInfo Big5TWHK = - { "x-x-big5", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo CNS116431 = - { "x-cns-11643-1", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo CNS116432 = - { "x-cns-11643-2", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo CNS116433 = - { "x-cns-11643-3", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo CNS116434 = - { "x-cns-11643-4", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo CNS116435 = - { "x-cns-11643-5", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo CNS116436 = - { "x-cns-11643-6", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo CNS116437 = - { "x-cns-11643-7", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo GB2312 = - { "gb_2312-80", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_SIMP, 0 }; -static nsFontCharSetInfo GB18030_0 = - { "gb18030.2000-0", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_SIMP, 0 }; -static nsFontCharSetInfo GB18030_1 = - { "gb18030.2000-1", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_SIMP, 0 }; -static nsFontCharSetInfo GBK = - { "x-gbk-noascii", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_SIMP, 0 }; -static nsFontCharSetInfo HKSCS = - { "hkscs-1", DoubleByteConvert, 1, - TT_OS2_CPR1_CHINESE_TRAD, 0 }; -static nsFontCharSetInfo JISX0208 = - { "jis_0208-1983", DoubleByteConvert, 1, - TT_OS2_CPR1_JAPANESE, 0 }; -static nsFontCharSetInfo JISX0212 = - { "jis_0212-1990", DoubleByteConvert, 1, - TT_OS2_CPR1_JAPANESE, 0 }; -static nsFontCharSetInfo KSC5601 = - { "ks_c_5601-1987", DoubleByteConvert, 1, - TT_OS2_CPR1_KO_WANSUNG | TT_OS2_CPR1_KO_JOHAB, 0 }; -static nsFontCharSetInfo X11Johab = - { "x-x11johab", DoubleByteConvert, 1, - TT_OS2_CPR1_KO_WANSUNG | TT_OS2_CPR1_KO_JOHAB, 0 }; -static nsFontCharSetInfo JohabNoAscii = - { "x-johab-noascii", DoubleByteConvert, 1, - TT_OS2_CPR1_KO_WANSUNG | TT_OS2_CPR1_KO_JOHAB, 0 }; -static nsFontCharSetInfo JamoTTF = - { "x-koreanjamo-0", DoubleByteConvert, 1, - TT_OS2_CPR1_KO_WANSUNG | TT_OS2_CPR1_KO_JOHAB, 0 }; -static nsFontCharSetInfo TamilTTF = - { "x-tamilttf-0", DoubleByteConvert, 0, - 0, 0 }; -static nsFontCharSetInfo CP1250 = - { "windows-1250", SingleByteConvert, 0, - TT_OS2_CPR1_LATIN2, TT_OS2_CPR2_LATIN2 }; -static nsFontCharSetInfo CP1251 = - { "windows-1251", SingleByteConvert, 0, - TT_OS2_CPR1_CYRILLIC, TT_OS2_CPR2_RUSSIAN }; -static nsFontCharSetInfo CP1252 = - { "windows-1252", SingleByteConvert, 0, - TT_OS2_CPR1_LATIN1 | TT_OS2_CPR1_MAC_ROMAN, - TT_OS2_CPR2_CA_FRENCH | TT_OS2_CPR2_PORTUGESE - | TT_OS2_CPR2_WE_LATIN1 | TT_OS2_CPR2_US }; -static nsFontCharSetInfo CP1253 = - { "windows-1253", SingleByteConvert, 0, - TT_OS2_CPR1_GREEK, TT_OS2_CPR2_GREEK | TT_OS2_CPR2_GREEK_437G }; -static nsFontCharSetInfo CP1257 = - { "windows-1257", SingleByteConvert, 0, - TT_OS2_CPR1_BALTIC, TT_OS2_CPR2_BALTIC }; - -#ifdef SUNCTL -/* Hindi range currently unsupported in FT2 range. Change TT* once we - arrive at a way to identify hindi */ -static nsFontCharSetInfo SunIndic = - { "x-sun-unicode-india-0", DoubleByteConvert, 0, - 0, 0 }; -#endif /* SUNCTL */ - -static nsFontCharSetInfo ISO106461 = - { nsnull, ISO10646Convert, 1, 0xFFFFFFFF, 0xFFFFFFFF }; - -static nsFontCharSetInfo AdobeSymbol = - { "Adobe-Symbol-Encoding", SingleByteConvert, 0, - TT_OS2_CPR1_SYMBOL, 0 }; -static nsFontCharSetInfo AdobeEuro = - { "x-adobe-euro", SingleByteConvert, 0, - 0, 0 }; - -#ifdef MOZ_MATHML -static nsFontCharSetInfo CMCMEX = - { "x-t1-cmex", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo CMCMSY = - { "x-t1-cmsy", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo CMCMR = - { "x-t1-cmr", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo CMCMMI = - { "x-t1-cmmi", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo Mathematica1 = - { "x-mathematica1", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo Mathematica2 = - { "x-mathematica2", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo Mathematica3 = - { "x-mathematica3", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo Mathematica4 = - { "x-mathematica4", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -static nsFontCharSetInfo Mathematica5 = - { "x-mathematica5", SingleByteConvert, 0, TT_OS2_CPR1_SYMBOL, 0}; -#endif /* MATHML */ - -#else - -static nsFontCharSetInfo USASCII = - { "us-ascii", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88591 = - { "ISO-8859-1", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88592 = - { "ISO-8859-2", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88593 = - { "ISO-8859-3", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88594 = - { "ISO-8859-4", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88595 = - { "ISO-8859-5", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88596 = - { "ISO-8859-6", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO885968x = - { "x-iso-8859-6-8-x", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO8859616 = - { "x-iso-8859-6-16", SingleByteConvert, 0 }; -static nsFontCharSetInfo IBM1046 = - { "x-IBM1046", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88597 = - { "ISO-8859-7", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO88598 = - { "ISO-8859-8", SingleByteConvert, 0 }; -// change from -// { "ISO-8859-8", SingleByteConvertReverse, 0, 0, 0 }; -// untill we fix the layout and ensure we only call this with pure RTL text -static nsFontCharSetInfo ISO88599 = - { "ISO-8859-9", SingleByteConvert, 0 }; -// no support for iso-8859-10 (Nordic/Icelandic) currently -// static nsFontCharSetInfo ISO885910 = -// { "ISO-8859-10", SingleByteConvert, 0, -// 0, TT_OS2_CPR2_NORDIC | TT_OS2_CPR2_ICELANDIC }; -// no support for iso-8859-12 (Vietnamese) currently -// static nsFontCharSetInfo ISO885912 = -// { "ISO-8859-12", SingleByteConvert, 0, -// TT_OS2_CPR1_VIETNAMESE, 0 }; -static nsFontCharSetInfo ISO885913 = - { "ISO-8859-13", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO885915 = - { "ISO-8859-15", SingleByteConvert, 0 }; -static nsFontCharSetInfo JISX0201 = - { "jis_0201", SingleByteConvert, 1 }; -static nsFontCharSetInfo KOI8R = - { "KOI8-R", SingleByteConvert, 0 }; -static nsFontCharSetInfo KOI8U = - { "KOI8-U", SingleByteConvert, 0 }; -static nsFontCharSetInfo TIS6202 = -/* Added to support thai context sensitive shaping if - * CTL extension is is in force */ -#ifdef SUNCTL - { "tis620-2", SingleByteConvert, 0 }; -#else - { "windows-874", SingleByteConvert, 0 }; -#endif /* SUNCTL */ -static nsFontCharSetInfo TIS620 = - { "TIS-620", SingleByteConvert, 0 }; -static nsFontCharSetInfo ISO885911 = - { "ISO-8859-11", SingleByteConvert, 0 }; -static nsFontCharSetInfo Big5 = - { "x-x-big5", DoubleByteConvert, 1 }; -// a kludge to distinguish zh-TW only fonts in Big5 (such as hpbig5-) -// from zh-TW/zh-HK common fonts in Big5 (such as big5-1) -static nsFontCharSetInfo Big5TWHK = - { "x-x-big5", DoubleByteConvert, 1 }; -static nsFontCharSetInfo CNS116431 = - { "x-cns-11643-1", DoubleByteConvert, 1 }; -static nsFontCharSetInfo CNS116432 = - { "x-cns-11643-2", DoubleByteConvert, 1 }; -static nsFontCharSetInfo CNS116433 = - { "x-cns-11643-3", DoubleByteConvert, 1 }; -static nsFontCharSetInfo CNS116434 = - { "x-cns-11643-4", DoubleByteConvert, 1 }; -static nsFontCharSetInfo CNS116435 = - { "x-cns-11643-5", DoubleByteConvert, 1 }; -static nsFontCharSetInfo CNS116436 = - { "x-cns-11643-6", DoubleByteConvert, 1 }; -static nsFontCharSetInfo CNS116437 = - { "x-cns-11643-7", DoubleByteConvert, 1 }; -static nsFontCharSetInfo GB2312 = - { "gb_2312-80", DoubleByteConvert, 1 }; -static nsFontCharSetInfo GB18030_0 = - { "gb18030.2000-0", DoubleByteConvert, 1 }; -static nsFontCharSetInfo GB18030_1 = - { "gb18030.2000-1", DoubleByteConvert, 1 }; -static nsFontCharSetInfo GBK = - { "x-gbk-noascii", DoubleByteConvert, 1 }; -static nsFontCharSetInfo HKSCS = - { "hkscs-1", DoubleByteConvert, 1 }; -static nsFontCharSetInfo JISX0208 = - { "jis_0208-1983", DoubleByteConvert, 1 }; -static nsFontCharSetInfo JISX0212 = - { "jis_0212-1990", DoubleByteConvert, 1 }; -static nsFontCharSetInfo KSC5601 = - { "ks_c_5601-1987", DoubleByteConvert, 1 }; -static nsFontCharSetInfo X11Johab = - { "x-x11johab", DoubleByteConvert, 1 }; -static nsFontCharSetInfo JohabNoAscii = - { "x-johab-noascii", DoubleByteConvert, 1 }; -static nsFontCharSetInfo JamoTTF = - { "x-koreanjamo-0", DoubleByteConvert, 1 }; -static nsFontCharSetInfo TamilTTF = - { "x-tamilttf-0", DoubleByteConvert, 0 }; -static nsFontCharSetInfo CP1250 = - { "windows-1250", SingleByteConvert, 0 }; -static nsFontCharSetInfo CP1251 = - { "windows-1251", SingleByteConvert, 0 }; -static nsFontCharSetInfo CP1252 = - { "windows-1252", SingleByteConvert, 0 }; -static nsFontCharSetInfo CP1253 = - { "windows-1253", SingleByteConvert, 0 }; -static nsFontCharSetInfo CP1257 = - { "windows-1257", SingleByteConvert, 0 }; - -#ifdef SUNCTL -/* Hindi range currently unsupported in FT2 range. Change TT* once we - arrive at a way to identify hindi */ -static nsFontCharSetInfo SunIndic = - { "x-sun-unicode-india-0", DoubleByteConvert, 0 }; -#endif /* SUNCTL */ - -static nsFontCharSetInfo ISO106461 = - { nsnull, ISO10646Convert, 1}; - -static nsFontCharSetInfo AdobeSymbol = - { "Adobe-Symbol-Encoding", SingleByteConvert, 0 }; -static nsFontCharSetInfo AdobeEuro = - { "x-adobe-euro", SingleByteConvert, 0 }; - -#ifdef MOZ_MATHML -static nsFontCharSetInfo CMCMEX = - { "x-t1-cmex", SingleByteConvert, 0}; -static nsFontCharSetInfo CMCMSY = - { "x-t1-cmsy", SingleByteConvert, 0}; -static nsFontCharSetInfo CMCMR = - { "x-t1-cmr", SingleByteConvert, 0}; -static nsFontCharSetInfo CMCMMI = - { "x-t1-cmmi", SingleByteConvert, 0}; -static nsFontCharSetInfo Mathematica1 = - { "x-mathematica1", SingleByteConvert, 0}; -static nsFontCharSetInfo Mathematica2 = - { "x-mathematica2", SingleByteConvert, 0}; -static nsFontCharSetInfo Mathematica3 = - { "x-mathematica3", SingleByteConvert, 0}; -static nsFontCharSetInfo Mathematica4 = - { "x-mathematica4", SingleByteConvert, 0}; -static nsFontCharSetInfo Mathematica5 = - { "x-mathematica5", SingleByteConvert, 0}; -#endif /* MATHML */ -#endif /* FREETYPE2 */ - -static nsFontLangGroup FLG_WESTERN = { "x-western", nsnull }; -static nsFontLangGroup FLG_RUSSIAN = { "x-cyrillic", nsnull }; -static nsFontLangGroup FLG_BALTIC = { "x-baltic", nsnull }; -static nsFontLangGroup FLG_CE = { "x-central-euro",nsnull }; -static nsFontLangGroup FLG_GREEK = { "el", nsnull }; -static nsFontLangGroup FLG_TURKISH = { "tr", nsnull }; -static nsFontLangGroup FLG_HEBREW = { "he", nsnull }; -static nsFontLangGroup FLG_ARABIC = { "ar", nsnull }; -static nsFontLangGroup FLG_THAI = { "th", nsnull }; -static nsFontLangGroup FLG_ZHCN = { "zh-CN", nsnull }; -static nsFontLangGroup FLG_ZHTW = { "zh-TW", nsnull }; -static nsFontLangGroup FLG_ZHHK = { "zh-HK", nsnull }; -static nsFontLangGroup FLG_ZHTWHK = { "x-zh-TWHK", nsnull }; // TW + HK -static nsFontLangGroup FLG_JA = { "ja", nsnull }; -static nsFontLangGroup FLG_KO = { "ko", nsnull }; -#ifdef SUNCTL -static nsFontLangGroup FLG_INDIC = { "x-devanagari", nsnull }; -#endif -static nsFontLangGroup FLG_TAMIL = { "x-tamil", nsnull }; -static nsFontLangGroup FLG_NONE = { nsnull, nsnull }; - -/* - * Normally, the charset of an X font can be determined simply by looking at - * the last 2 fields of the long XLFD font name (CHARSET_REGISTRY and - * CHARSET_ENCODING). However, there are a number of special cases: - * - * Sometimes, X server vendors use the same name to mean different things. For - * example, IRIX uses "cns11643-1" to mean the 2nd plane of CNS 11643, while - * Solaris uses that name for the 1st plane. - * - * Some X server vendors use certain names for something completely different. - * For example, some Solaris fonts say "gb2312.1980-0" but are actually ASCII - * fonts. These cases can be detected by looking at the POINT_SIZE and - * AVERAGE_WIDTH fields. If the average width is half the point size, this is - * an ASCII font, not GB 2312. - * - * Some fonts say "fontspecific" in the CHARSET_ENCODING field. Their charsets - * depend on the FAMILY_NAME. For example, the following is a "Symbol" font: - * - * -adobe-symbol-medium-r-normal--17-120-100-100-p-95-adobe-fontspecific - * - * Some vendors use one name to mean 2 different things, depending on the font. - * For example, AIX has some "ksc5601.1987-0" fonts that require the 8th bit of - * both bytes to be zero, while other fonts require them to be set to one. - * These cases can be distinguished by looking at the FOUNDRY field, but a - * better way is to look at XFontStruct.min_byte1. - */ -static nsFontCharSetMap gCharSetMap[] = -{ - { "-ascii", &FLG_NONE, &Unknown }, - { "-ibm pc", &FLG_NONE, &Unknown }, - { "adobe-fontspecific", &FLG_NONE, &Special }, - { "ansi-1251", &FLG_RUSSIAN, &CP1251 }, - // On Solaris, big5-0 is used for ASCII-only fonts while in XFree86, - // it's for Big5 fonts without US-ASCII. When a non-Solaris binary - // is displayed on a Solaris X server, this would break. -#ifndef SOLARIS - { "big5-0", &FLG_ZHTWHK, &Big5TWHK }, // for both TW and HK -#else - { "big5-0", &FLG_ZHTW, &USASCII }, -#endif - { "big5-1", &FLG_ZHTWHK, &Big5TWHK }, // ditto - { "big5.et-0", &FLG_ZHTW, &Big5 }, - { "big5.et.ext-0", &FLG_ZHTW, &Big5 }, - { "big5.etext-0", &FLG_ZHTW, &Big5 }, - { "big5.hku-0", &FLG_ZHTW, &Big5 }, - { "big5.hku-1", &FLG_ZHTW, &Big5 }, - { "big5.pc-0", &FLG_ZHTW, &Big5 }, - { "big5.shift-0", &FLG_ZHTW, &Big5 }, - { "big5hkscs-0", &FLG_ZHHK, &HKSCS }, - { "cns11643.1986-1", &FLG_ZHTW, &CNS116431 }, - { "cns11643.1986-2", &FLG_ZHTW, &CNS116432 }, - { "cns11643.1992-1", &FLG_ZHTW, &CNS116431 }, - { "cns11643.1992.1-0", &FLG_ZHTW, &CNS116431 }, - { "cns11643.1992-12", &FLG_NONE, &Unknown }, - { "cns11643.1992.2-0", &FLG_ZHTW, &CNS116432 }, - { "cns11643.1992-2", &FLG_ZHTW, &CNS116432 }, - { "cns11643.1992-3", &FLG_ZHTW, &CNS116433 }, - { "cns11643.1992.3-0", &FLG_ZHTW, &CNS116433 }, - { "cns11643.1992.4-0", &FLG_ZHTW, &CNS116434 }, - { "cns11643.1992-4", &FLG_ZHTW, &CNS116434 }, - { "cns11643.1992.5-0", &FLG_ZHTW, &CNS116435 }, - { "cns11643.1992-5", &FLG_ZHTW, &CNS116435 }, - { "cns11643.1992.6-0", &FLG_ZHTW, &CNS116436 }, - { "cns11643.1992-6", &FLG_ZHTW, &CNS116436 }, - { "cns11643.1992.7-0", &FLG_ZHTW, &CNS116437 }, - { "cns11643.1992-7", &FLG_ZHTW, &CNS116437 }, - { "cns11643-1", &FLG_ZHTW, &CNS116431 }, - { "cns11643-2", &FLG_ZHTW, &CNS116432 }, - { "cns11643-3", &FLG_ZHTW, &CNS116433 }, - { "cns11643-4", &FLG_ZHTW, &CNS116434 }, - { "cns11643-5", &FLG_ZHTW, &CNS116435 }, - { "cns11643-6", &FLG_ZHTW, &CNS116436 }, - { "cns11643-7", &FLG_ZHTW, &CNS116437 }, - { "cp1251-1", &FLG_RUSSIAN, &CP1251 }, - { "dec-dectech", &FLG_NONE, &Unknown }, - { "dtsymbol-1", &FLG_NONE, &Unknown }, - { "fontspecific-0", &FLG_NONE, &Unknown }, - { "gb2312.1980-0", &FLG_ZHCN, &GB2312 }, - { "gb2312.1980-1", &FLG_ZHCN, &GB2312 }, - { "gb13000.1993-1", &FLG_ZHCN, &GBK }, - { "gb18030.2000-0", &FLG_ZHCN, &GB18030_0 }, - { "gb18030.2000-1", &FLG_ZHCN, &GB18030_1 }, - { "gbk-0", &FLG_ZHCN, &GBK }, - { "gbk1988.1989-0", &FLG_ZHCN, &USASCII }, - { "hkscs-1", &FLG_ZHHK, &HKSCS }, - { "hp-japanese15", &FLG_NONE, &Unknown }, - { "hp-japaneseeuc", &FLG_NONE, &Unknown }, - { "hp-roman8", &FLG_NONE, &Unknown }, - { "hp-schinese15", &FLG_NONE, &Unknown }, - { "hp-tchinese15", &FLG_NONE, &Unknown }, - { "hp-tchinesebig5", &FLG_ZHTW, &Big5 }, - { "hp-wa", &FLG_NONE, &Unknown }, - { "hpbig5-", &FLG_ZHTW, &Big5 }, - { "hphkbig5-", &FLG_ZHHK, &HKSCS }, - { "hproc16-", &FLG_NONE, &Unknown }, - { "ibm-1046", &FLG_ARABIC, &IBM1046 }, - { "ibm-1252", &FLG_NONE, &Unknown }, - { "ibm-850", &FLG_NONE, &Unknown }, - { "ibm-fontspecific", &FLG_NONE, &Unknown }, - { "ibm-sbdcn", &FLG_NONE, &Unknown }, - { "ibm-sbdtw", &FLG_NONE, &Unknown }, - { "ibm-special", &FLG_NONE, &Unknown }, - { "ibm-udccn", &FLG_NONE, &Unknown }, - { "ibm-udcjp", &FLG_NONE, &Unknown }, - { "ibm-udctw", &FLG_NONE, &Unknown }, - { "iso646.1991-irv", &FLG_NONE, &Unknown }, - { "iso8859-1", &FLG_WESTERN, &ISO88591 }, - { "iso8859-13", &FLG_BALTIC, &ISO885913 }, - { "iso8859-15", &FLG_WESTERN, &ISO885915 }, - { "iso8859-1@cn", &FLG_NONE, &Unknown }, - { "iso8859-1@kr", &FLG_NONE, &Unknown }, - { "iso8859-1@tw", &FLG_NONE, &Unknown }, - { "iso8859-1@zh", &FLG_NONE, &Unknown }, - { "iso8859-2", &FLG_CE, &ISO88592 }, - { "iso8859-3", &FLG_WESTERN, &ISO88593 }, - { "iso8859-4", &FLG_BALTIC, &ISO88594 }, - { "iso8859-5", &FLG_RUSSIAN, &ISO88595 }, - { "iso8859-6", &FLG_ARABIC, &ISO88596 }, - { "iso8859-6.8x", &FLG_ARABIC, &ISO885968x }, - { "iso8859-6.16" , &FLG_ARABIC, &ISO8859616 }, - { "iso8859-7", &FLG_GREEK, &ISO88597 }, - { "iso8859-8", &FLG_HEBREW, &ISO88598 }, - { "iso8859-9", &FLG_TURKISH, &ISO88599 }, - { "iso10646-1", &FLG_NONE, &ISO106461 }, - { "jisx0201.1976-0", &FLG_JA, &JISX0201 }, - { "jisx0201.1976-1", &FLG_JA, &JISX0201 }, - { "jisx0208.1983-0", &FLG_JA, &JISX0208 }, - { "jisx0208.1990-0", &FLG_JA, &JISX0208 }, - { "jisx0212.1990-0", &FLG_JA, &JISX0212 }, - { "koi8-r", &FLG_RUSSIAN, &KOI8R }, - { "koi8-u", &FLG_RUSSIAN, &KOI8U }, - { "johab-1", &FLG_KO, &X11Johab }, - { "johabs-1", &FLG_KO, &X11Johab }, - { "johabsh-1", &FLG_KO, &X11Johab }, - { "ksc5601.1987-0", &FLG_KO, &KSC5601 }, - // we can handle GR fonts with GL encoders (KSC5601 and GB2312) - // See |DoubleByteConvert|. - { "ksc5601.1987-1", &FLG_KO, &KSC5601 }, - { "ksc5601.1992-3", &FLG_KO, &JohabNoAscii }, - { "koreanjamo-0", &FLG_KO, &JamoTTF }, - { "microsoft-cp1250", &FLG_CE, &CP1250 }, - { "microsoft-cp1251", &FLG_RUSSIAN, &CP1251 }, - { "microsoft-cp1252", &FLG_WESTERN, &CP1252 }, - { "microsoft-cp1253", &FLG_GREEK, &CP1253 }, - { "microsoft-cp1257", &FLG_BALTIC, &CP1257 }, - { "misc-fontspecific", &FLG_NONE, &Unknown }, - { "sgi-fontspecific", &FLG_NONE, &Unknown }, - { "sun-fontspecific", &FLG_NONE, &Unknown }, - { "sunolcursor-1", &FLG_NONE, &Unknown }, - { "sunolglyph-1", &FLG_NONE, &Unknown }, - { "symbol-fontspecific",&FLG_NONE, &Special }, - { "tis620.2529-1", &FLG_THAI, &TIS620 }, - { "tis620.2533-0", &FLG_THAI, &TIS620 }, - { "tis620.2533-1", &FLG_THAI, &TIS620 }, - { "tis620-0", &FLG_THAI, &TIS620 }, - { "tis620-2", &FLG_THAI, &TIS6202 }, - { "iso8859-11", &FLG_THAI, &ISO885911 }, - { "ucs2.cjk-0", &FLG_NONE, &ISO106461 }, - { "ucs2.cjk_china-0", &FLG_ZHCN, &ISO106461 }, - { "iso10646.2000-cn", &FLG_ZHCN, &ISO106461 }, // HP/UX - { "ucs2.cjk_japan-0", &FLG_JA, &ISO106461 }, - { "ucs2.cjk_korea-0", &FLG_KO, &ISO106461 }, - { "korean.ucs2-0", &FLG_KO, &ISO106461 }, // HP/UX - { "ucs2.cjk_taiwan-0", &FLG_ZHTW, &ISO106461 }, - { "ucs2.thai-0", &FLG_THAI, &ISO106461 }, - { "tamilttf-0", &FLG_TAMIL, &TamilTTF }, -#ifdef SUNCTL - { "sun.unicode.india-0",&FLG_INDIC, &SunIndic }, -#endif /* SUNCTL */ - - { nsnull, nsnull, nsnull } -}; - -static nsFontFamilyName gFamilyNameTable[] = -{ - { "arial", "helvetica" }, - { "courier new", "courier" }, - { "times new roman", "times" }, - -#ifdef MOZ_MATHML - { "cmex", "cmex10" }, - { "cmsy", "cmsy10" }, - { "-moz-math-text", "times" }, - { "-moz-math-symbol", "symbol" }, -#endif - - { nsnull, nsnull } -}; - -static nsFontCharSetMap gNoneCharSetMap[] = { { nsnull }, }; - -static nsFontCharSetMap gSpecialCharSetMap[] = -{ - { "symbol-adobe-fontspecific", &FLG_NONE, &AdobeSymbol }, - { "euromono-adobe-fontspecific", &FLG_NONE, &AdobeEuro }, - { "eurosans-adobe-fontspecific", &FLG_NONE, &AdobeEuro }, - { "euroserif-adobe-fontspecific", &FLG_NONE, &AdobeEuro }, - -#ifdef MOZ_MATHML - { "cmex10-adobe-fontspecific", &FLG_NONE, &CMCMEX }, - { "cmsy10-adobe-fontspecific", &FLG_NONE, &CMCMSY }, - { "cmr10-adobe-fontspecific", &FLG_NONE, &CMCMR }, - { "cmmi10-adobe-fontspecific", &FLG_NONE, &CMCMMI }, - - { "math1-adobe-fontspecific", &FLG_NONE, &Mathematica1 }, - { "math2-adobe-fontspecific", &FLG_NONE, &Mathematica2 }, - { "math3-adobe-fontspecific", &FLG_NONE, &Mathematica3 }, - { "math4-adobe-fontspecific", &FLG_NONE, &Mathematica4 }, - { "math5-adobe-fontspecific", &FLG_NONE, &Mathematica5 }, - - { "math1mono-adobe-fontspecific", &FLG_NONE, &Mathematica1 }, - { "math2mono-adobe-fontspecific", &FLG_NONE, &Mathematica2 }, - { "math3mono-adobe-fontspecific", &FLG_NONE, &Mathematica3 }, - { "math4mono-adobe-fontspecific", &FLG_NONE, &Mathematica4 }, - { "math5mono-adobe-fontspecific", &FLG_NONE, &Mathematica5 }, -#endif - - { nsnull, nsnull } -}; - -static nsFontPropertyName gStretchNames[] = -{ - { "block", 5 }, // XXX - { "bold", 7 }, // XXX - { "double wide", 9 }, - { "medium", 5 }, - { "narrow", 3 }, - { "normal", 5 }, - { "semicondensed", 4 }, - { "wide", 7 }, - - { nsnull, 0 } -}; - -static nsFontPropertyName gWeightNames[] = -{ - { "black", 900 }, - { "bold", 700 }, - { "book", 400 }, - { "demi", 600 }, - { "demibold", 600 }, - { "light", 300 }, - { "medium", 400 }, - { "regular", 400 }, - - { nsnull, 0 } -}; - -static char* -atomToName(nsIAtom* aAtom) -{ - const char *namePRU; - aAtom->GetUTF8String(&namePRU); - return ToNewCString(nsDependentCString(namePRU)); -} - -static PRUint16* gUserDefinedCCMap = nsnull; -static PRUint16* gEmptyCCMap = nsnull; - -// -// smart quotes (and other special chars) in Asian (double byte) -// fonts are too large to use is western fonts. -// Here we define those characters. -// XXX: This array can (and need, for performance) be made |const| when -// GTK port of gfx gets sync'd with Xlib port for multiple device contexts. - -#include "dbyte_special_chars.ccmap" -DEFINE_CCMAP(gDoubleByteSpecialCharsCCMap, /* nothing */); - -static PRBool -FreeCharSetMap(nsHashKey* aKey, void* aData, void* aClosure) -{ - nsFontCharSetMap* charsetMap = (nsFontCharSetMap*) aData; - NS_IF_RELEASE(charsetMap->mInfo->mConverter); - NS_IF_RELEASE(charsetMap->mInfo->mLangGroup); - FreeCCMap(charsetMap->mInfo->mCCMap); - - return PR_TRUE; -} - -static PRBool -FreeFamily(nsHashKey* aKey, void* aData, void* aClosure) -{ - delete (nsFontFamily*) aData; - - return PR_TRUE; -} - -static void -FreeStretch(nsFontStretch* aStretch) -{ - PR_smprintf_free(aStretch->mScalable); - - for (PRInt32 count = aStretch->mScaledFonts.Count()-1; count >= 0; --count) { - nsFontGTK *font = (nsFontGTK*)aStretch->mScaledFonts.ElementAt(count); - if (font) delete font; - } - // aStretch->mScaledFonts.Clear(); handled by delete of aStretch - - for (int i = 0; i < aStretch->mSizesCount; i++) { - delete aStretch->mSizes[i]; - } - delete [] aStretch->mSizes; - delete aStretch; -} - -static void -FreeWeight(nsFontWeight* aWeight) -{ - for (int i = 0; i < 9; i++) { - if (aWeight->mStretches[i]) { - for (int j = i + 1; j < 9; j++) { - if (aWeight->mStretches[j] == aWeight->mStretches[i]) { - aWeight->mStretches[j] = nsnull; - } - } - FreeStretch(aWeight->mStretches[i]); - } - } - delete aWeight; -} - -static void -FreeStyle(nsFontStyle* aStyle) -{ - for (int i = 0; i < 9; i++) { - if (aStyle->mWeights[i]) { - for (int j = i + 1; j < 9; j++) { - if (aStyle->mWeights[j] == aStyle->mWeights[i]) { - aStyle->mWeights[j] = nsnull; - } - } - FreeWeight(aStyle->mWeights[i]); - } - } - delete aStyle; -} - -PRBool -FreeNode(nsHashKey* aKey, void* aData, void* aClosure) -{ - nsFontNode* node = (nsFontNode*) aData; - for (int i = 0; i < 3; i++) { - if (node->mStyles[i]) { - for (int j = i + 1; j < 3; j++) { - if (node->mStyles[j] == node->mStyles[i]) { - node->mStyles[j] = nsnull; - } - } - FreeStyle(node->mStyles[i]); - } - } - delete node; - - return PR_TRUE; -} - -static PRBool -FreeNodeArray(nsHashKey* aKey, void* aData, void* aClosure) -{ - nsFontNodeArray* nodes = (nsFontNodeArray*) aData; - delete nodes; - - return PR_TRUE; -} - -static void -FreeGlobals(void) -{ - // XXX complete this - - gInitialized = 0; - -#ifdef MOZ_ENABLE_FREETYPE2 - nsFT2FontNode::FreeGlobals(); -#endif - -#ifdef ENABLE_X_FONT_BANNING - if (gFontRejectRegEx) { - regfree(gFontRejectRegEx); - delete gFontRejectRegEx; - gFontRejectRegEx = nsnull; - } - - if (gFontAcceptRegEx) { - regfree(gFontAcceptRegEx); - delete gFontAcceptRegEx; - gFontAcceptRegEx = nsnull; - } -#endif /* ENABLE_X_FONT_BANNING */ - - nsXFontAAScaledBitmap::FreeGlobals(); - nsX11AlphaBlendFreeGlobals(); - - if (gAliases) { - delete gAliases; - gAliases = nsnull; - } - NS_IF_RELEASE(gCharSetManager); - if (gCharSetMaps) { - gCharSetMaps->Reset(FreeCharSetMap, nsnull); - delete gCharSetMaps; - gCharSetMaps = nsnull; - } - if (gFamilies) { - gFamilies->Reset(FreeFamily, nsnull); - delete gFamilies; - gFamilies = nsnull; - } - if (gGlobalList) { - delete gGlobalList; - gGlobalList = nsnull; - } - if (gCachedFFRESearches) { - gCachedFFRESearches->Reset(FreeNodeArray, nsnull); - delete gCachedFFRESearches; - gCachedFFRESearches = nsnull; - } - if (gFFRENodes) { - gFFRENodes->Reset(FreeNode, nsnull); - delete gFFRENodes; - gFFRENodes = nsnull; - } - if (gAFRENodes) { - gAFRENodes->Reset(FreeNode, nsnull); - delete gAFRENodes; - gAFRENodes = nsnull; - } - NS_IF_RELEASE(gPref); - if (gSpecialCharSets) { - gSpecialCharSets->Reset(FreeCharSetMap, nsnull); - delete gSpecialCharSets; - gSpecialCharSets = nsnull; - } - if (gStretches) { - delete gStretches; - gStretches = nsnull; - } - NS_IF_RELEASE(gUnicode); - NS_IF_RELEASE(gUserDefined); - NS_IF_RELEASE(gZHTW); - NS_IF_RELEASE(gZHHK); - NS_IF_RELEASE(gZHTWHK); - NS_IF_RELEASE(gUserDefinedConverter); - NS_IF_RELEASE(gUsersLocale); - NS_IF_RELEASE(gWesternLocale); - NS_IF_RELEASE(gFontSubConverter); - if (gWeights) { - delete gWeights; - gWeights = nsnull; - } - nsFontCharSetMap* charSetMap; - for (charSetMap=gCharSetMap; charSetMap->mFontLangGroup; charSetMap++) { - NS_IF_RELEASE(charSetMap->mFontLangGroup->mFontLangGroupAtom); - charSetMap->mFontLangGroup->mFontLangGroupAtom = nsnull; - } - FreeCCMap(gUserDefinedCCMap); - FreeCCMap(gEmptyCCMap); -} - -/* - * Initialize all the font lookup hash tables and other globals - */ -static nsresult -InitGlobals(nsIDeviceContext *aDevice) -{ -#ifdef NS_FONT_DEBUG - /* First check gfx/src/gtk/-specific env var "NS_FONT_DEBUG_GTK", - * then the more general "NS_FONT_DEBUG" if "NS_FONT_DEBUG_GTK" - * is not present */ - const char *debug = PR_GetEnv("NS_FONT_DEBUG_GTK"); - if (!debug) { - debug = PR_GetEnv("NS_FONT_DEBUG"); - } - - if (debug) { - PR_sscanf(debug, "%lX", &gFontDebug); - } -#endif /* NS_FONT_DEBUG */ - - NS_ENSURE_TRUE(nsnull != aDevice, NS_ERROR_NULL_POINTER); - - aDevice->GetCanonicalPixelScale(gDevScale); - - CallGetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &gCharSetManager); - if (!gCharSetManager) { - FreeGlobals(); - return NS_ERROR_FAILURE; - } - CallGetService(NS_PREF_CONTRACTID, &gPref); - if (!gPref) { - FreeGlobals(); - return NS_ERROR_FAILURE; - } - - nsCompressedCharMap empty_ccmapObj; - gEmptyCCMap = empty_ccmapObj.NewCCMap(); - if (!gEmptyCCMap) - return NS_ERROR_OUT_OF_MEMORY; - - // get the "disable double byte font special chars" setting - PRBool val = PR_TRUE; - nsresult rv = gPref->GetBoolPref("font.allow_double_byte_special_chars", &val); - if (NS_SUCCEEDED(rv)) - gAllowDoubleByteSpecialChars = val; - - PRInt32 scale_minimum = 0; - rv = gPref->GetIntPref("font.scale.outline.min", &scale_minimum); - if (NS_SUCCEEDED(rv)) { - gOutlineScaleMinimum = scale_minimum; - SIZE_FONT_PRINTF(("gOutlineScaleMinimum = %d", gOutlineScaleMinimum)); - } - - val = PR_TRUE; - rv = gPref->GetBoolPref("font.scale.aa_bitmap.enable", &val); - if (NS_SUCCEEDED(rv)) { - gAABitmapScaleEnabled = val; - SIZE_FONT_PRINTF(("gAABitmapScaleEnabled = %d", gAABitmapScaleEnabled)); - } - - val = PR_FALSE; - rv = gPref->GetBoolPref("font.scale.aa_bitmap.always", &val); - if (NS_SUCCEEDED(rv)) { - gAABitmapScaleAlways = val; - SIZE_FONT_PRINTF(("gAABitmapScaleAlways = %d", gAABitmapScaleAlways)); - } - - rv = gPref->GetIntPref("font.scale.aa_bitmap.min", &scale_minimum); - if (NS_SUCCEEDED(rv)) { - gAABitmapScaleMinimum = scale_minimum; - SIZE_FONT_PRINTF(("gAABitmapScaleMinimum = %d", gAABitmapScaleMinimum)); - } - - PRInt32 percent = 0; - rv = gPref->GetIntPref("font.scale.aa_bitmap.undersize", &percent); - if ((NS_SUCCEEDED(rv)) && (percent)) { - gAABitmapUndersize = percent/100.0; - SIZE_FONT_PRINTF(("gAABitmapUndersize = %g", gAABitmapUndersize)); - } - percent = 0; - rv = gPref->GetIntPref("font.scale.aa_bitmap.oversize", &percent); - if ((NS_SUCCEEDED(rv)) && (percent)) { - gAABitmapOversize = percent/100.0; - SIZE_FONT_PRINTF(("gAABitmapOversize = %g", gAABitmapOversize)); - } - PRInt32 int_val = 0; - rv = gPref->GetIntPref("font.scale.aa_bitmap.dark_text.min", &int_val); - if (NS_SUCCEEDED(rv)) { - gAASBDarkTextMinValue = int_val; - SIZE_FONT_PRINTF(("gAASBDarkTextMinValue = %d", gAASBDarkTextMinValue)); - } - nsXPIDLCString str; - rv = gPref->GetCharPref("font.scale.aa_bitmap.dark_text.gain", - getter_Copies(str)); - if (NS_SUCCEEDED(rv)) { - gAASBDarkTextGain = atof(str.get()); - SIZE_FONT_PRINTF(("gAASBDarkTextGain = %g", gAASBDarkTextGain)); - } - int_val = 0; - rv = gPref->GetIntPref("font.scale.aa_bitmap.light_text.min", &int_val); - if (NS_SUCCEEDED(rv)) { - gAASBLightTextMinValue = int_val; - SIZE_FONT_PRINTF(("gAASBLightTextMinValue = %d", gAASBLightTextMinValue)); - } - rv = gPref->GetCharPref("font.scale.aa_bitmap.light_text.gain", - getter_Copies(str)); - if (NS_SUCCEEDED(rv)) { - gAASBLightTextGain = atof(str.get()); - SIZE_FONT_PRINTF(("gAASBLightTextGain = %g", gAASBLightTextGain)); - } - - rv = gPref->GetIntPref("font.scale.bitmap.min", &scale_minimum); - if (NS_SUCCEEDED(rv)) { - gBitmapScaleMinimum = scale_minimum; - SIZE_FONT_PRINTF(("gBitmapScaleMinimum = %d", gBitmapScaleMinimum)); - } - percent = 0; - gPref->GetIntPref("font.scale.bitmap.oversize", &percent); - if (percent) { - gBitmapOversize = percent/100.0; - SIZE_FONT_PRINTF(("gBitmapOversize = %g", gBitmapOversize)); - } - percent = 0; - gPref->GetIntPref("font.scale.bitmap.undersize", &percent); - if (percent) { - gBitmapUndersize = percent/100.0; - SIZE_FONT_PRINTF(("gBitmapUndersize = %g", gBitmapUndersize)); - } - - PRBool force_outline_scaled_fonts = gForceOutlineScaledFonts; - rv = gPref->GetBoolPref("font.x11.force_outline_scaled_fonts", &force_outline_scaled_fonts); - if (NS_SUCCEEDED(rv)) { - gForceOutlineScaledFonts = force_outline_scaled_fonts; - } - - PRBool scale_bitmap_fonts_with_devscale = gScaleBitmapFontsWithDevScale; - - rv = gPref->GetBoolPref("font.x11.scale_bitmap_fonts_with_devscale", &scale_bitmap_fonts_with_devscale); - if (NS_SUCCEEDED(rv)) { - gScaleBitmapFontsWithDevScale = scale_bitmap_fonts_with_devscale; - } - - gFFRENodes = new nsHashtable(); - if (!gFFRENodes) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gAFRENodes = new nsHashtable(); - if (!gAFRENodes) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gCachedFFRESearches = new nsHashtable(); - if (!gCachedFFRESearches) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gFamilies = new nsHashtable(); - if (!gFamilies) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gAliases = new nsHashtable(); - if (!gAliases) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - nsFontFamilyName* f = gFamilyNameTable; - while (f->mName) { - nsCStringKey key(f->mName); - gAliases->Put(&key, (void *)f->mXName); - f++; - } - gWeights = new nsHashtable(); - if (!gWeights) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - nsFontPropertyName* p = gWeightNames; - while (p->mName) { - nsCStringKey key(p->mName); - gWeights->Put(&key, (void*) p->mValue); - p++; - } - gStretches = new nsHashtable(); - if (!gStretches) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - p = gStretchNames; - while (p->mName) { - nsCStringKey key(p->mName); - gStretches->Put(&key, (void*) p->mValue); - p++; - } - gCharSetMaps = new nsHashtable(); - if (!gCharSetMaps) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - nsFontCharSetMap* charSetMap = gCharSetMap; - while (charSetMap->mName) { - nsCStringKey key(charSetMap->mName); - gCharSetMaps->Put(&key, charSetMap); - charSetMap++; - } - gSpecialCharSets = new nsHashtable(); - if (!gSpecialCharSets) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - nsFontCharSetMap* specialCharSetMap = gSpecialCharSetMap; - while (specialCharSetMap->mName) { - nsCStringKey key(specialCharSetMap->mName); - gSpecialCharSets->Put(&key, specialCharSetMap); - specialCharSetMap++; - } - - gUnicode = NS_NewAtom("x-unicode"); - if (!gUnicode) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gUserDefined = NS_NewAtom(USER_DEFINED); - if (!gUserDefined) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gZHTW = NS_NewAtom("zh-TW"); - if (!gZHTW) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gZHHK = NS_NewAtom("zh-HK"); - if (!gZHHK) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - gZHTWHK = NS_NewAtom("x-zh-TWHK"); - if (!gZHTWHK) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - - // the user's locale - nsCOMPtr langService; - langService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID); - if (langService) { - NS_IF_ADDREF(gUsersLocale = langService->GetLocaleLanguageGroup()); - } - if (!gUsersLocale) { - gUsersLocale = NS_NewAtom("x-western"); - } - gWesternLocale = NS_NewAtom("x-western"); - if (!gUsersLocale) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - - rv = nsX11AlphaBlendInitGlobals(GDK_DISPLAY()); - if (NS_FAILED(rv) || (!nsX11AlphaBlend::CanAntiAlias())) { - gAABitmapScaleEnabled = PR_FALSE; - } - - if (gAABitmapScaleEnabled) { - gAABitmapScaleEnabled = nsXFontAAScaledBitmap::InitGlobals(GDK_DISPLAY(), - DefaultScreen(GDK_DISPLAY())); - } - -#ifdef ENABLE_X_FONT_BANNING - /* get the font banning pattern */ - nsXPIDLCString fbpattern; - rv = gPref->GetCharPref("font.x11.rejectfontpattern", getter_Copies(fbpattern)); - if (NS_SUCCEEDED(rv)) { - gFontRejectRegEx = new regex_t; - if (!gFontRejectRegEx) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - - /* Compile the pattern - and return an error if we get an invalid pattern... */ - if (regcomp(gFontRejectRegEx, fbpattern.get(), REG_EXTENDED|REG_NOSUB) != REG_OK) { - PR_LOG(FontMetricsGTKLM, PR_LOG_DEBUG, ("Invalid rejectfontpattern '%s'\n", fbpattern.get())); - BANNED_FONT_PRINTF(("Invalid font.x11.rejectfontpattern '%s'", fbpattern.get())); - delete gFontRejectRegEx; - gFontRejectRegEx = nsnull; - - FreeGlobals(); - return NS_ERROR_INVALID_ARG; - } - } - - rv = gPref->GetCharPref("font.x11.acceptfontpattern", getter_Copies(fbpattern)); - if (NS_SUCCEEDED(rv)) { - gFontAcceptRegEx = new regex_t; - if (!gFontAcceptRegEx) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - - /* Compile the pattern - and return an error if we get an invalid pattern... */ - if (regcomp(gFontAcceptRegEx, fbpattern.get(), REG_EXTENDED|REG_NOSUB) != REG_OK) { - PR_LOG(FontMetricsGTKLM, PR_LOG_DEBUG, ("Invalid acceptfontpattern '%s'\n", fbpattern.get())); - BANNED_FONT_PRINTF(("Invalid font.x11.acceptfontpattern '%s'", fbpattern.get())); - delete gFontAcceptRegEx; - gFontAcceptRegEx = nsnull; - - FreeGlobals(); - return NS_ERROR_INVALID_ARG; - } - } -#endif /* ENABLE_X_FONT_BANNING */ - -#ifdef MOZ_ENABLE_FREETYPE2 - rv = nsFT2FontNode::InitGlobals(); - if (NS_FAILED(rv)) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } -#endif - - gInitialized = 1; - - return NS_OK; -} - -// do the 8 to 16 bit conversion on the stack -// if the data is less than this size -#define WIDEN_8_TO_16_BUF_SIZE 1024 - -// handle 8 bit data with a 16 bit font -gint -Widen8To16AndMove(const gchar *char_p, - gint char_len, - XChar2b *xchar2b_p) -{ - int i; - for (i=0; ibyte1 = 0; - (xchar2b_p++)->byte2 = *char_p++; - } - return(char_len*2); -} - -// handle 8 bit data with a 16 bit font -gint -Widen8To16AndGetWidth (nsXFont *xFont, - const gchar *text, - gint text_length) -{ - NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size"); - XChar2b buf[WIDEN_8_TO_16_BUF_SIZE]; - XChar2b *p = buf; - int uchar_size; - gint rawWidth; - - if (text_length > WIDEN_8_TO_16_BUF_SIZE) { - p = (XChar2b*)PR_Malloc(text_length*sizeof(XChar2b)); - if (!p) return(0); // handle malloc failure - } - - uchar_size = Widen8To16AndMove(text, text_length, p); - rawWidth = xFont->TextWidth16(p, uchar_size/2); - - if (text_length > WIDEN_8_TO_16_BUF_SIZE) { - PR_Free((char*)p); - } - return(rawWidth); -} - -void -Widen8To16AndDraw (GdkDrawable *drawable, - nsXFont *xFont, - GdkGC *gc, - gint x, - gint y, - const gchar *text, - gint text_length) -{ - NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size"); - XChar2b buf[WIDEN_8_TO_16_BUF_SIZE]; - XChar2b *p = buf; - int uchar_size; - - if (text_length > WIDEN_8_TO_16_BUF_SIZE) { - p = (XChar2b*)PR_Malloc(text_length*sizeof(XChar2b)); - if (!p) return; // handle malloc failure - } - - uchar_size = Widen8To16AndMove(text, text_length, p); - xFont->DrawText16(drawable, gc, x, y, p, uchar_size/2); - - if (text_length > WIDEN_8_TO_16_BUF_SIZE) { - PR_Free((char*)p); - } -} - -#ifdef MOZ_MATHML - -void -Widen8To16AndGetTextExtents (nsXFont *xFont, - const gchar *text, - gint text_length, - gint *lbearing, - gint *rbearing, - gint *width, - gint *ascent, - gint *descent) -{ - NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size"); - XChar2b buf[WIDEN_8_TO_16_BUF_SIZE]; - XChar2b *p = buf; - int uchar_size; - - if (text_length > WIDEN_8_TO_16_BUF_SIZE) { - p = (XChar2b*)PR_Malloc(text_length*sizeof(XChar2b)); - if (!p) { // handle malloc failure - *lbearing = 0; - *rbearing = 0; - *width = 0; - *ascent = 0; - *descent = 0; - return; - } - } - - uchar_size = Widen8To16AndMove(text, text_length, p); - xFont->TextExtents16(p, uchar_size/2, - lbearing, - rbearing, - width, - ascent, - descent); - - if (text_length > WIDEN_8_TO_16_BUF_SIZE) { - PR_Free((char*)p); - } -} - -#endif /* MOZ_MATHML */ - -nsFontMetricsGTK::nsFontMetricsGTK() - : mFonts() // I'm not sure what the common size is here - I generally - // see 2-5 entries. For now, punt and let it be allocated later. We can't - // make it an nsAutoVoidArray since it's a cString array. - // XXX mFontIsGeneric will generally need to be the same size; right now - // it's an nsAutoVoidArray. If the average is under 8, that's ok. -{ - gFontMetricsGTKCount++; -} - -nsFontMetricsGTK::~nsFontMetricsGTK() -{ - // do not free mGeneric here - - if (mLoadedFonts) { - PR_Free(mLoadedFonts); - mLoadedFonts = nsnull; - } - - if (mSubstituteFont) { - delete mSubstituteFont; - mSubstituteFont = nsnull; - } - - mWesternFont = nsnull; - mCurrentFont = nsnull; - - if (mDeviceContext) { - // Notify our device context that owns us so that it can update its font cache - mDeviceContext->FontMetricsDeleted(this); - mDeviceContext = nsnull; - } - - if (!--gFontMetricsGTKCount) { - FreeGlobals(); - } -} - -NS_IMPL_ISUPPORTS1(nsFontMetricsGTK, nsIFontMetrics) - -static PRBool -IsASCIIFontName(const nsString& aName) -{ - PRUint32 len = aName.Length(); - const PRUnichar* str = aName.get(); - for (PRUint32 i = 0; i < len; i++) { - /* - * X font names are printable ASCII, ignore others (for now) - */ - if ((str[i] < 0x20) || (str[i] > 0x7E)) { - return PR_FALSE; - } - } - - return PR_TRUE; -} - -static PRBool -FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData) -{ -#ifdef REALLY_NOISY_FONTS - printf("font = '"); - fputs(NS_LossyConvertUTF16toASCII(aFamily).get(), stdout); - printf("'\n"); -#endif - - if (!IsASCIIFontName(aFamily)) { - return PR_TRUE; // skip and continue - } - - nsCAutoString name; - name.AssignWithConversion(aFamily.get()); - ToLowerCase(name); - nsFontMetricsGTK* metrics = (nsFontMetricsGTK*) aData; - metrics->mFonts.AppendCString(name); - metrics->mFontIsGeneric.AppendElement((void*) aGeneric); - if (aGeneric) { - metrics->mGeneric = metrics->mFonts.CStringAt(metrics->mFonts.Count() - 1); - return PR_FALSE; // stop - } - - return PR_TRUE; // continue -} - -NS_IMETHODIMP nsFontMetricsGTK::Init(const nsFont& aFont, nsIAtom* aLangGroup, - nsIDeviceContext* aContext) -{ - NS_ASSERTION(!(nsnull == aContext), "attempt to init fontmetrics with null device context"); - - nsresult res = NS_OK; - mDocConverterType = nsnull; - - if (!gInitialized) { - res = InitGlobals(aContext); - if (NS_FAILED(res)) - return res; - } - - mFont = aFont; - mLangGroup = aLangGroup; - - mDeviceContext = aContext; - - float app2dev; - app2dev = mDeviceContext->AppUnitsToDevUnits(); - - mPixelSize = NSToIntRound(app2dev * mFont.size); - // Make sure to clamp the pixel size to something reasonable so we - // don't make the X server blow up. - mPixelSize = PR_MIN(gdk_screen_height() * FONT_MAX_FONT_SCALE, mPixelSize); - - mStretchIndex = 4; // normal - mStyleIndex = mFont.style; - - mFont.EnumerateFamilies(FontEnumCallback, this); - nsXPIDLCString value; - const char* langGroup; - mLangGroup->GetUTF8String(&langGroup); - if (!mGeneric) { - nsCAutoString name("font.default."); - name.Append(langGroup); - gPref->CopyCharPref(name.get(), getter_Copies(value)); - if (value.get()) { - mDefaultFont = value.get(); - } - else { - mDefaultFont = "serif"; - } - mGeneric = &mDefaultFont; - } - - if (mLangGroup) { - nsCAutoString name("font.min-size."); - if (mGeneric->Equals("monospace")) { - name.Append("fixed"); - } - else { - name.Append("variable"); - } - name.Append(char('.')); - name.Append(langGroup); - PRInt32 minimum = 0; - res = gPref->GetIntPref(name.get(), &minimum); - if (NS_FAILED(res)) { - gPref->GetDefaultIntPref(name.get(), &minimum); - } - if (minimum < 0) { - minimum = 0; - } - if (mPixelSize < minimum) { - mPixelSize = minimum; - } - } - - if (mLangGroup.get() == gUserDefined) { - if (!gUserDefinedConverter) { - res = gCharSetManager->GetUnicodeEncoderRaw("x-user-defined", - &gUserDefinedConverter); - if (NS_FAILED(res)) { - return res; - } - res = gUserDefinedConverter->SetOutputErrorBehavior( - gUserDefinedConverter->kOnError_Replace, nsnull, '?'); - nsCOMPtr mapper = - do_QueryInterface(gUserDefinedConverter); - if (mapper) { - gUserDefinedCCMap = MapperToCCMap(mapper); - if (!gUserDefinedCCMap) - return NS_ERROR_OUT_OF_MEMORY; - } - } - - nsCAutoString name("font.name."); - name.Append(*mGeneric); - name.Append(char('.')); - name.Append(USER_DEFINED); - gPref->CopyCharPref(name.get(), getter_Copies(value)); - if (value.get()) { - mUserDefined = value.get(); - mIsUserDefined = 1; - } - } - - mWesternFont = FindFont('a'); - if (!mWesternFont) { - return NS_ERROR_FAILURE; - } - - - mCurrentFont = mWesternFont; - - RealizeFont(); - - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::Destroy() -{ - mDeviceContext = nsnull; - return NS_OK; -} - -void nsFontMetricsGTK::RealizeFont() -{ - float f; - f = mDeviceContext->DevUnitsToAppUnits(); - -#ifdef MOZ_ENABLE_FREETYPE2 - if (mWesternFont->IsFreeTypeFont()) { - nsFreeTypeFont *ft = (nsFreeTypeFont *)mWesternFont; - if (!ft) - return; - // now that there are multiple font types (eg: core X fonts - // and TrueType fonts) there should be a common set of methods - // to get the metrics info from the font object. These methods - // probably should be virtual functions defined in nsFontGTK. - int lineSpacing = ft->ascent() + ft->descent(); - if (lineSpacing > mWesternFont->mSize) { - mLeading = nscoord((lineSpacing - mWesternFont->mSize) * f); - } - else { - mLeading = 0; - } - mEmHeight = PR_MAX(1, nscoord(mWesternFont->mSize * f)); - mEmAscent = nscoord(ft->ascent() * mWesternFont->mSize * f / lineSpacing); - mEmDescent = mEmHeight - mEmAscent; - - mMaxHeight = nscoord((ft->max_ascent() + ft->max_descent()) * f); - mMaxAscent = nscoord(ft->max_ascent() * f) ; - mMaxDescent = nscoord(ft->max_descent() * f); - - mMaxAdvance = nscoord(ft->max_width() * f); - // X may screw up if we try to measure/draw more than 32767 pixels in - // one operation - mMaxStringLength = (PRInt32)floor(32767.0/ft->max_width()); - mMaxStringLength = PR_MAX(1, mMaxStringLength); - - // 56% of ascent, best guess for non-true type - mXHeight = NSToCoordRound((float) ft->ascent()* f * 0.56f); - - PRUnichar space = (PRUnichar)' '; - mSpaceWidth = NSToCoordRound(ft->GetWidth(&space, 1) * f); - - PRUnichar averageX = (PRUnichar)'x'; - mAveCharWidth = NSToCoordRound(ft->GetWidth(&averageX, 1) * f); - - unsigned long pr = 0; - if (ft->getXHeight(pr)) { - mXHeight = nscoord(pr * f); - } - - float height; - long val; - if (ft->underlinePosition(val)) { - /* this will only be provided from adobe .afm fonts and TrueType - * fonts served by xfsft (not xfstt!) */ - mUnderlineOffset = -NSToIntRound(val * f); - } - else { - height = ft->ascent() + ft->descent(); - mUnderlineOffset = -NSToIntRound(MAX (1, floor (0.1 * height + 0.5)) * f); - } - - if (ft->underline_thickness(pr)) { - /* this will only be provided from adobe .afm fonts */ - mUnderlineSize = nscoord(MAX(f, NSToIntRound(pr * f))); - } - else { - height = ft->ascent() + ft->descent(); - mUnderlineSize = NSToIntRound(MAX(1, floor (0.05 * height + 0.5)) * f); - } - - if (ft->superscript_y(val)) { - mSuperscriptOffset = nscoord(MAX(f, NSToIntRound(val * f))); - } - else { - mSuperscriptOffset = mXHeight; - } - - if (ft->subscript_y(val)) { - mSubscriptOffset = nscoord(MAX(f, NSToIntRound(val * f))); - } - else { - mSubscriptOffset = mXHeight; - } - - /* need better way to calculate this */ - mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0); - mStrikeoutSize = mUnderlineSize; - - return; - } -#endif - nsXFont *xFont = mWesternFont->GetXFont(); - XFontStruct *fontInfo = xFont->GetXFontStruct(); - f = mDeviceContext->DevUnitsToAppUnits(); - - nscoord lineSpacing = nscoord((fontInfo->ascent + fontInfo->descent) * f); - mEmHeight = PR_MAX(1, nscoord(mWesternFont->mSize * f)); - if (lineSpacing > mEmHeight) { - mLeading = lineSpacing - mEmHeight; - } - else { - mLeading = 0; - } - mMaxHeight = nscoord((fontInfo->ascent + fontInfo->descent) * f); - mMaxAscent = nscoord(fontInfo->ascent * f); - mMaxDescent = nscoord(fontInfo->descent * f); - - if (lineSpacing == 0) { - mEmAscent = mEmHeight; - } - else { - mEmAscent = nscoord(mMaxAscent * mEmHeight / lineSpacing); - } - mEmDescent = mEmHeight - mEmAscent; - - mMaxAdvance = nscoord(fontInfo->max_bounds.width * f); - // X may screw up if we try to measure/draw more than 32767 pixels in - // one operation. - mMaxStringLength = (PRInt32)floor(32767.0/fontInfo->max_bounds.width); - mMaxStringLength = PR_MAX(1, mMaxStringLength); - - gint rawWidth, rawAverage; - if ((fontInfo->min_byte1 == 0) && (fontInfo->max_byte1 == 0)) { - rawWidth = xFont->TextWidth8(" ", 1); - rawAverage = xFont->TextWidth8("x", 1); - } - else { - XChar2b _16bit_space, _16bit_x; - _16bit_space.byte1 = 0; - _16bit_space.byte2 = ' '; - _16bit_x.byte1 = 0; - _16bit_x.byte2 = 'x'; - rawWidth = xFont->TextWidth16(&_16bit_space, sizeof(_16bit_space)/2); - rawAverage = xFont->TextWidth16(&_16bit_x, sizeof( _16bit_x)/2); - } - mSpaceWidth = NSToCoordRound(rawWidth * f); - mAveCharWidth = NSToCoordRound(rawAverage * f); - - unsigned long pr = 0; - if (xFont->GetXFontProperty(XA_X_HEIGHT, &pr) && pr != 0 && - pr < 0x00ffffff) // Bug 43214: arbitrary to exclude garbage values - { - mXHeight = nscoord(pr * f); -#ifdef REALLY_NOISY_FONTS - printf("xHeight=%d\n", mXHeight); -#endif - } - else - { - // 56% of ascent, best guess for non-true type - mXHeight = NSToCoordRound((float) fontInfo->ascent* f * 0.56f); - } - - if (xFont->GetXFontProperty(XA_UNDERLINE_POSITION, &pr)) - { - /* this will only be provided from adobe .afm fonts and TrueType - * fonts served by xfsft (not xfstt!) */ - mUnderlineOffset = -NSToIntRound(pr * f); -#ifdef REALLY_NOISY_FONTS - printf("underlineOffset=%d\n", mUnderlineOffset); -#endif - } - else - { - /* this may need to be different than one for those weird asian fonts */ - float height; - height = fontInfo->ascent + fontInfo->descent; - mUnderlineOffset = -NSToIntRound(MAX (1, floor (0.1 * height + 0.5)) * f); - } - - if (xFont->GetXFontProperty(XA_UNDERLINE_THICKNESS, &pr)) - { - /* this will only be provided from adobe .afm fonts */ - mUnderlineSize = nscoord(MAX(f, NSToIntRound(pr * f))); -#ifdef REALLY_NOISY_FONTS - printf("underlineSize=%d\n", mUnderlineSize); -#endif - } - else - { - float height; - height = fontInfo->ascent + fontInfo->descent; - mUnderlineSize = NSToIntRound(MAX(1, floor (0.05 * height + 0.5)) * f); - } - - if (xFont->GetXFontProperty(XA_SUPERSCRIPT_Y, &pr)) - { - mSuperscriptOffset = nscoord(MAX(f, NSToIntRound(pr * f))); -#ifdef REALLY_NOISY_FONTS - printf("superscriptOffset=%d\n", mSuperscriptOffset); -#endif - } - else - { - mSuperscriptOffset = mXHeight; - } - - if (xFont->GetXFontProperty(XA_SUBSCRIPT_Y, &pr)) - { - mSubscriptOffset = nscoord(MAX(f, NSToIntRound(pr * f))); -#ifdef REALLY_NOISY_FONTS - printf("subscriptOffset=%d\n", mSubscriptOffset); -#endif - } - else - { - mSubscriptOffset = mXHeight; - } - - /* need better way to calculate this */ - mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0); - mStrikeoutSize = mUnderlineSize; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetXHeight(nscoord& aResult) -{ - aResult = mXHeight; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetSuperscriptOffset(nscoord& aResult) -{ - aResult = mSuperscriptOffset; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetSubscriptOffset(nscoord& aResult) -{ - aResult = mSubscriptOffset; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetStrikeout(nscoord& aOffset, nscoord& aSize) -{ - aOffset = mStrikeoutOffset; - aSize = mStrikeoutSize; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetUnderline(nscoord& aOffset, nscoord& aSize) -{ - aOffset = mUnderlineOffset; - aSize = mUnderlineSize; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetHeight(nscoord &aHeight) -{ - aHeight = mMaxHeight; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetNormalLineHeight(nscoord &aHeight) -{ - aHeight = mEmHeight + mLeading; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetLeading(nscoord &aLeading) -{ - aLeading = mLeading; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetEmHeight(nscoord &aHeight) -{ - aHeight = mEmHeight; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetEmAscent(nscoord &aAscent) -{ - aAscent = mEmAscent; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetEmDescent(nscoord &aDescent) -{ - aDescent = mEmDescent; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetMaxHeight(nscoord &aHeight) -{ - aHeight = mMaxHeight; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetMaxAscent(nscoord &aAscent) -{ - aAscent = mMaxAscent; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetMaxDescent(nscoord &aDescent) -{ - aDescent = mMaxDescent; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetMaxAdvance(nscoord &aAdvance) -{ - aAdvance = mMaxAdvance; - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetAveCharWidth(nscoord &aAveCharWidth) -{ - aAveCharWidth = mAveCharWidth; - return NS_OK; -} - -PRInt32 nsFontMetricsGTK::GetMaxStringLength() -{ - return mMaxStringLength; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetLangGroup(nsIAtom** aLangGroup) -{ - if (!aLangGroup) { - return NS_ERROR_NULL_POINTER; - } - - *aLangGroup = mLangGroup; - NS_IF_ADDREF(*aLangGroup); - - return NS_OK; -} - -NS_IMETHODIMP nsFontMetricsGTK::GetFontHandle(nsFontHandle &aHandle) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsFontGTK* -nsFontMetricsGTK::LocateFont(PRUint32 aChar, PRInt32 & aCount) -{ - nsFontGTK *font; - PRInt32 i; - - // see if one of our loaded fonts can represent the character - for (i = 0; i < aCount; ++i) { - font = (nsFontGTK*)mLoadedFonts[i]; - if (CCMAP_HAS_CHAR_EXT(font->mCCMap, aChar)) - return font; - } - - font = FindFont(aChar); - aCount = mLoadedFontsCount; // update since FindFont() can change it - - return font; -} - -nsresult -nsFontMetricsGTK::ResolveForwards(const PRUnichar *aString, - PRUint32 aLength, - nsFontSwitchCallbackGTK aFunc, - void *aData) -{ - NS_ASSERTION(aString || !aLength, "invalid call"); - const PRUnichar* firstChar = aString; - const PRUnichar* currChar = firstChar; - const PRUnichar* lastChar = aString + aLength; - nsFontGTK* currFont; - nsFontGTK* nextFont; - PRInt32 count; - nsFontSwitchGTK fontSwitch; - - if (firstChar == lastChar) - return NS_OK; - - count = mLoadedFontsCount; - - if (NS_IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && NS_IS_LOW_SURROGATE(*(currChar+1))) { - currFont = LocateFont(SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count); - currChar += 2; - } - else { - currFont = LocateFont(*currChar, count); - ++currChar; - } - - //This if block is meant to speedup the process in normal situation, when - //most characters can be found in first font - if (currFont == mLoadedFonts[0]) { - while (currChar < lastChar && CCMAP_HAS_CHAR_EXT(currFont->mCCMap,*currChar)) - ++currChar; - fontSwitch.mFontGTK = currFont; - if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData)) - return NS_OK; - if (currChar == lastChar) - return NS_OK; - // continue with the next substring, re-using the available loaded fonts - firstChar = currChar; - if (NS_IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && NS_IS_LOW_SURROGATE(*(currChar+1))) { - currFont = LocateFont(SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count); - currChar += 2; - } - else { - currFont = LocateFont(*currChar, count); - ++currChar; - } - } - - // see if we can keep the same font for adjacent characters - PRInt32 lastCharLen; - while (currChar < lastChar) { - if (NS_IS_HIGH_SURROGATE(*currChar) && (currChar+1) < lastChar && NS_IS_LOW_SURROGATE(*(currChar+1))) { - nextFont = LocateFont(SURROGATE_TO_UCS4(*currChar, *(currChar+1)), count); - lastCharLen = 2; - } - else { - nextFont = LocateFont(*currChar, count); - lastCharLen = 1; - } - if (nextFont != currFont) { - // We have a substring that can be represented with the same font, and - // we are about to switch fonts, it is time to notify our caller. - fontSwitch.mFontGTK = currFont; - if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData)) - return NS_OK; - // continue with the next substring, re-using the available loaded fonts - firstChar = currChar; - - currFont = nextFont; // use the font found earlier for the char - } - currChar += lastCharLen; - } - - //do it for last part of the string - fontSwitch.mFontGTK = currFont; - (*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData); - return NS_OK; -} - -NS_IMETHODIMP -nsFontMetricsGTK::GetSpaceWidth(nscoord &aSpaceWidth) -{ - aSpaceWidth = mSpaceWidth; - return NS_OK; -} - -/* - * CSS2 "font properties": - * font-family - * font-style - * font-variant - * font-weight - * font-stretch - * font-size - * font-size-adjust - * font - */ - -/* - * CSS2 "font descriptors": - * font-family - * font-style - * font-variant - * font-weight - * font-stretch - * font-size - * unicode-range - * units-per-em - * src - * panose-1 - * stemv - * stemh - * slope - * cap-height - * x-height - * ascent - * descent - * widths - * bbox - * definition-src - * baseline - * centerline - * mathline - * topline - */ - -/* - * XLFD 1.5 "FontName fields": - * FOUNDRY - * FAMILY_NAME - * WEIGHT_NAME - * SLANT - * SETWIDTH_NAME - * ADD_STYLE_NAME - * PIXEL_SIZE - * POINT_SIZE - * RESOLUTION_X - * RESOLUTION_Y - * SPACING - * AVERAGE_WIDTH - * CHARSET_REGISTRY - * CHARSET_ENCODING - * XLFD example: - * -adobe-times-medium-r-normal--17-120-100-100-p-84-iso8859-1 - */ - -/* - * XLFD 1.5 "font properties": - * FOUNDRY - * FAMILY_NAME - * WEIGHT_NAME - * SLANT - * SETWIDTH_NAME - * ADD_STYLE_NAME - * PIXEL_SIZE - * POINT_SIZE - * RESOLUTION_X - * RESOLUTION_Y - * SPACING - * AVERAGE_WIDTH - * CHARSET_REGISTRY - * CHARSET_ENCODING - * MIN_SPACE - * NORM_SPACE - * MAX_SPACE - * END_SPACE - * AVG_CAPITAL_WIDTH - * AVG_LOWERCASE_WIDTH - * QUAD_WIDTH - * FIGURE_WIDTH - * SUPERSCRIPT_X - * SUPERSCRIPT_Y - * SUBSCRIPT_X - * SUBSCRIPT_Y - * SUPERSCRIPT_SIZE - * SUBSCRIPT_SIZE - * SMALL_CAP_SIZE - * UNDERLINE_POSITION - * UNDERLINE_THICKNESS - * STRIKEOUT_ASCENT - * STRIKEOUT_DESCENT - * ITALIC_ANGLE - * CAP_HEIGHT - * X_HEIGHT - * RELATIVE_SETWIDTH - * RELATIVE_WEIGHT - * WEIGHT - * RESOLUTION - * FONT - * FACE_NAME - * FULL_NAME - * COPYRIGHT - * NOTICE - * DESTINATION - * FONT_TYPE - * FONT_VERSION - * RASTERIZER_NAME - * RASTERIZER_VERSION - * RAW_ASCENT - * RAW_DESCENT - * RAW_* - * AXIS_NAMES - * AXIS_LIMITS - * AXIS_TYPES - */ - -/* - * XLFD 1.5 BDF 2.1 properties: - * FONT_ASCENT - * FONT_DESCENT - * DEFAULT_CHAR - */ - -/* - * CSS2 algorithm, in the following order: - * font-family: FAMILY_NAME (and FOUNDRY? (XXX)) - * font-style: SLANT (XXX: XLFD's RI and RO) - * font-variant: implemented in mozilla/layout/html/base/src/nsTextFrame.cpp - * font-weight: RELATIVE_WEIGHT (XXX), WEIGHT (XXX), WEIGHT_NAME - * font-size: XFontStruct.max_bounds.ascent + descent - * - * The following property is not specified in the algorithm spec. It will be - * inserted between the font-weight and font-size steps for now: - * font-stretch: RELATIVE_SETWIDTH (XXX), SETWIDTH_NAME - */ - -/* - * XXX: Things to investigate in the future: - * ADD_STYLE_NAME font-family's serif and sans-serif - * SPACING font-family's monospace; however, there are very few - * proportional fonts in non-Latin-1 charsets, so beware in - * font prefs dialog - * AVERAGE_WIDTH none (see SETWIDTH_NAME) - */ - -static gint -SingleByteConvert(nsFontCharSetInfo* aSelf, XFontStruct* aFont, - const PRUnichar* aSrcBuf, PRInt32 aSrcLen, char* aDestBuf, PRInt32 aDestLen) -{ - gint count = 0; - if (aSelf->mConverter) { - aSelf->mConverter->Convert(aSrcBuf, &aSrcLen, aDestBuf, &aDestLen); - count = aDestLen; - } - - return count; -} - -/* -static void -ReverseBuffer(char* aBuf, gint count) -{ - char *head, *tail, *med; - head = aBuf; - tail = &aBuf[count-1]; - med = &aBuf[count/2]; - - while(head < med) - { - char tmp = *head; - *head++ = *tail; - *tail-- = tmp; - } -} -*/ - -// the following code assume all the PRUnichar is draw in the same -// direction- left to right, without mixing with characters which should -// draw from right to left. This mean it should not be used untill the -// upper level code resolve bi-di and ensure this assumption. otherwise -// it may break non-bidi pages on a system which have hebrew/arabic fonts -/* -static gint -SingleByteConvertReverse(nsFontCharSetInfo* aSelf, const PRUnichar* aSrcBuf, - PRInt32 aSrcLen, char* aDestBuf, PRInt32 aDestLen) -{ - gint count = SingleByteConvert(aSelf, aSrcBuf, - aSrcLen, aDestBuf, aDestLen); - ReverseBuffer(aDestBuf, count); - return count; -} -*/ - -static gint -DoubleByteConvert(nsFontCharSetInfo* aSelf, XFontStruct* aFont, - const PRUnichar* aSrcBuf, PRInt32 aSrcLen, char* aDestBuf, PRInt32 aDestLen) -{ - gint count; - if (aSelf->mConverter) { - aSelf->mConverter->Convert(aSrcBuf, &aSrcLen, aDestBuf, &aDestLen); - count = aDestLen; - if (count > 0) { - if ((aDestBuf[0] & 0x80) && (!(aFont->max_byte1 & 0x80))) { - for (PRInt32 i = 0; i < aDestLen; i++) { - aDestBuf[i] &= 0x7F; - } - } - // We're using a GL encoder (KSC5601 or GB2312) but the font is a GR font. - // (ksc5601.1987-1 or gb2312.1980-1) - else if ((!(aDestBuf[0] & 0x80)) && (aFont->min_byte1 & 0x80)) { - for (PRInt32 i = 0; i < aDestLen; i++) { - aDestBuf[i] |= 0x80; - } - } - } - } - else { - count = 0; - } - - return count; -} - -static gint -ISO10646Convert(nsFontCharSetInfo* aSelf, XFontStruct* aFont, - const PRUnichar* aSrcBuf, PRInt32 aSrcLen, char* aDestBuf, PRInt32 aDestLen) -{ - aDestLen /= 2; - if (aSrcLen > aDestLen) { - aSrcLen = aDestLen; - } - if (aSrcLen < 0) { - aSrcLen = 0; - } - XChar2b* dest = (XChar2b*) aDestBuf; - for (PRInt32 i = 0; i < aSrcLen; i++) { - dest[i].byte1 = (aSrcBuf[i] >> 8); - dest[i].byte2 = (aSrcBuf[i] & 0xFF); - } - - return (gint) aSrcLen * 2; -} - -#ifdef DEBUG - -static void -CheckMap(nsFontCharSetMap* aEntry) -{ - while (aEntry->mName) { - if (aEntry->mInfo->mCharSet) { - // used to use NS_NewAtom?? - nsresult res; - nsCOMPtr converter; - res = gCharSetManager->GetUnicodeEncoderRaw(aEntry->mInfo->mCharSet, - getter_AddRefs(converter)); - if (NS_FAILED(res)) { - printf("=== %s failed (%s)\n", aEntry->mInfo->mCharSet, __FILE__); - } - } - aEntry++; - } -} - -static void -CheckSelf(void) -{ - CheckMap(gCharSetMap); - -#ifdef MOZ_MATHML - // For this to pass, the ucvmath module must be built as well - CheckMap(gSpecialCharSetMap); -#endif -} - -#endif /* DEBUG */ - -static PRBool -SetUpFontCharSetInfo(nsFontCharSetInfo* aSelf) -{ - -#ifdef DEBUG - static int checkedSelf = 0; - if (!checkedSelf) { - CheckSelf(); - checkedSelf = 1; - } -#endif - - nsresult res; - // used NS_NewAtom before?? - nsIUnicodeEncoder* converter = nsnull; - res = gCharSetManager->GetUnicodeEncoderRaw(aSelf->mCharSet, &converter); - if (NS_SUCCEEDED(res)) { - aSelf->mConverter = converter; - res = converter->SetOutputErrorBehavior(converter->kOnError_Replace, - nsnull, '?'); - nsCOMPtr mapper = do_QueryInterface(converter); - if (mapper) { - aSelf->mCCMap = MapperToCCMap(mapper); - if (aSelf->mCCMap) { -#ifdef DEBUG_bzbarsky - NS_WARNING(nsPrintfCString("\n\ncharset = %s", aSelf->mCharSet).get()); -#endif /* DEBUG */ - - /* - * We used to disable special characters like smart quotes - * in CJK fonts because if they are quite a bit larger than - * western glyphs and we did not want glyph fill-in to use them - * in single byte documents. - * - * Now, single byte documents find these special chars before - * the CJK fonts are searched so this is no longer needed - * but is useful when trying to determine which font(s) the - * special chars are found in. - */ - if ((aSelf->Convert == DoubleByteConvert) - && (!gAllowDoubleByteSpecialChars)) { - PRUint16* ccmap = aSelf->mCCMap; - PRUint32 page = CCMAP_BEGIN_AT_START_OF_MAP; - const PRUint16* specialmap = gDoubleByteSpecialCharsCCMap; - while (NextNonEmptyCCMapPage(specialmap, &page)) { - PRUint32 pagechar = page; - for (int i=0; i < CCMAP_BITS_PER_PAGE; i++) { - if (CCMAP_HAS_CHAR(specialmap, pagechar)) - CCMAP_UNSET_CHAR(ccmap, pagechar); - pagechar++; - } - } - } - return PR_TRUE; - } - } - else { - NS_WARNING("cannot get nsICharRepresentable"); - } - } - else { - NS_WARNING("cannot get Unicode converter"); - } - - // - // always try to return a map even if it is empty - // - nsCompressedCharMap empty_ccmapObj; - aSelf->mCCMap = empty_ccmapObj.NewCCMap(); - - // return false if unable to alloc a map - if (aSelf->mCCMap == nsnull) - return PR_FALSE; - - return PR_TRUE; -} - -#undef DEBUG_DUMP_TREE -#ifdef DEBUG_DUMP_TREE - -static char* gDumpStyles[3] = { "normal", "italic", "oblique" }; - -static PRIntn -DumpCharSet(PLHashEntry* he, PRIntn i, void* arg) -{ - printf(" %s\n", (char*) he->key); - nsFontCharSet* charSet = (nsFontCharSet*) he->value; - for (int sizeIndex = 0; sizeIndex < charSet->mSizesCount; sizeIndex++) { - nsFontGTK* size = &charSet->mSizes[sizeIndex]; - printf(" %d %s\n", size->mSize, size->mName); - } - return HT_ENUMERATE_NEXT; -} - -static void -DumpFamily(nsFontFamily* aFamily) -{ - for (int styleIndex = 0; styleIndex < 3; styleIndex++) { - nsFontStyle* style = aFamily->mStyles[styleIndex]; - if (style) { - printf(" style: %s\n", gDumpStyles[styleIndex]); - for (int weightIndex = 0; weightIndex < 8; weightIndex++) { - nsFontWeight* weight = style->mWeights[weightIndex]; - if (weight) { - printf(" weight: %d\n", (weightIndex + 1) * 100); - for (int stretchIndex = 0; stretchIndex < 9; stretchIndex++) { - nsFontStretch* stretch = weight->mStretches[stretchIndex]; - if (stretch) { - printf(" stretch: %d\n", stretchIndex + 1); - PL_HashTableEnumerateEntries(stretch->mCharSets, DumpCharSet, - nsnull); - } - } - } - } - } - } -} - -// this existing debug code was broken and I have partly fixed it -static PRBool -DumpFamilyEnum(nsHashKey* hashKey, void *aData, void* closure) -{ - printf("family: %s\n", - NS_LossyConvertUTF16toASCII(*NS_STATIC_CAST(nsString*,he->key))); - nsFontFamily* family = (nsFontFamily*) he->value; - DumpFamily(family); - - return HT_ENUMERATE_NEXT; -} - -static void -DumpTree(void) -{ - gFamilies->Enumerate(DumpFamilyEnum, nsnull); -} -#endif /* DEBUG_DUMP_TREE */ - -struct nsFontSearch -{ - nsFontMetricsGTK* mMetrics; - PRUint32 mChar; - nsFontGTK* mFont; -}; - -#if 0 -static void -GetUnderlineInfo(nsXFont* aFont, unsigned long* aPositionX2, - unsigned long* aThickness) -{ - /* - * XLFD 1.5 says underline position defaults descent/2. - * Hence we return position*2 to avoid rounding error. - */ - if (aFont->GetXFontProperty(XA_UNDERLINE_POSITION, aPositionX2)) { - *aPositionX2 *= 2; - } - else { - *aPositionX2 = aFont->max_bounds.descent; - } - - /* - * XLFD 1.5 says underline thickness defaults to cap stem width. - * We don't know what that is, so we just take the thickness of "_". - * This way, we get thicker underlines for bold fonts. - */ - if (!xFont->GetXFontProperty(XA_UNDERLINE_THICKNESS, aThickness)) { - int dir, ascent, descent; - XCharStruct overall; - XTextExtents(aFont, "_", 1, &dir, &ascent, &descent, &overall); - *aThickness = (overall.ascent + overall.descent); - } -} -#endif /* 0 */ - -static PRUint16* -GetMapFor10646Font(XFontStruct* aFont) -{ - if (!aFont->per_char) - return nsnull; - - nsCompressedCharMap ccmapObj; - PRInt32 minByte1 = aFont->min_byte1; - PRInt32 maxByte1 = aFont->max_byte1; - PRInt32 minByte2 = aFont->min_char_or_byte2; - PRInt32 maxByte2 = aFont->max_char_or_byte2; - PRInt32 charsPerRow = maxByte2 - minByte2 + 1; - for (PRInt32 row = minByte1; row <= maxByte1; row++) { - PRInt32 offset = (((row - minByte1) * charsPerRow) - minByte2); - for (PRInt32 cell = minByte2; cell <= maxByte2; cell++) { - XCharStruct* bounds = &aFont->per_char[offset + cell]; - // From Section 8.5 Font Metrics in the Xlib programming manual: - // A nonexistent character is represented with all members of its XCharStruct set to zero. - if (bounds->ascent || - bounds->descent || - bounds->lbearing || - bounds->rbearing || - bounds->width || - bounds->attributes) { - ccmapObj.SetChar((row << 8) | cell); - } - } - } - PRUint16 *ccmap = ccmapObj.NewCCMap(); - return ccmap; -} - -PRBool -nsFontGTK::IsEmptyFont(XFontStruct* xFont) -{ - - // - // scan and see if we can find at least one glyph - // - if (xFont->per_char) { - PRInt32 minByte1 = xFont->min_byte1; - PRInt32 maxByte1 = xFont->max_byte1; - PRInt32 minByte2 = xFont->min_char_or_byte2; - PRInt32 maxByte2 = xFont->max_char_or_byte2; - PRInt32 charsPerRow = maxByte2 - minByte2 + 1; - for (PRInt32 row = minByte1; row <= maxByte1; row++) { - PRInt32 offset = (((row - minByte1) * charsPerRow) - minByte2); - for (PRInt32 cell = minByte2; cell <= maxByte2; cell++) { - XCharStruct* bounds = &xFont->per_char[offset + cell]; - if (bounds->ascent || bounds->descent) { - return PR_FALSE; - } - } - } - } - - return PR_TRUE; -} - -void -nsFontGTK::LoadFont(void) -{ - if (mAlreadyCalledLoadFont) { - return; - } - - mAlreadyCalledLoadFont = PR_TRUE; - GdkFont* gdkFont; - NS_ASSERTION(!mFont, "mFont should not be loaded"); - if (mAABaseSize==0) { - NS_ASSERTION(!mFontHolder, "mFontHolder should not be loaded"); - gdk_error_trap_push(); - gdkFont = ::gdk_font_load(mName); - gdk_error_trap_pop(); - if (!gdkFont) - return; - mXFont = new nsXFontNormal(gdkFont); - } - else { - NS_ASSERTION(mFontHolder, "mFontHolder should be loaded"); - gdkFont = mFontHolder; - mXFont = new nsXFontAAScaledBitmap(GDK_DISPLAY(), - DefaultScreen(GDK_DISPLAY()), - gdkFont, mSize, mAABaseSize); - } - - NS_ASSERTION(mXFont,"failed to load mXFont"); - if (!mXFont) - return; - if (!mXFont->LoadFont()) { - delete mXFont; - mXFont = nsnull; - return; - } - - if (gdkFont) { - XFontStruct* xFont = mXFont->GetXFontStruct(); - XFontStruct* xFont_with_per_char; - if (mAABaseSize==0) - xFont_with_per_char = xFont; - else - xFont_with_per_char = (XFontStruct *)GDK_FONT_XFONT(mFontHolder); - - mMaxAscent = xFont->ascent; - mMaxDescent = xFont->descent; - - if (mCharSetInfo == &ISO106461) { - mCCMap = GetMapFor10646Font(xFont_with_per_char); - if (!mCCMap) { - mXFont->UnloadFont(); - mXFont = nsnull; - ::gdk_font_unref(gdkFont); - mFontHolder = nsnull; - return; - } - } - -// -// since we are very close to a release point -// limit the risk of this fix -// please remove soon -// -// Redhat 6.2 Japanese has invalid jisx201 fonts -// Solaris 2.6 has invalid cns11643 fonts for planes 4-7 -if ((mCharSetInfo == &JISX0201) - || (mCharSetInfo == &CNS116434) - || (mCharSetInfo == &CNS116435) - || (mCharSetInfo == &CNS116436) - || (mCharSetInfo == &CNS116437) - ) { - - if (IsEmptyFont(xFont_with_per_char)) { -#ifdef NS_FONT_DEBUG_LOAD_FONT - if (gFontDebug & NS_FONT_DEBUG_LOAD_FONT) { - printf("\n"); - printf("***************************************\n"); - printf("invalid font \"%s\", %s %d\n", mName, __FILE__, __LINE__); - printf("***************************************\n"); - printf("\n"); - } -#endif - mXFont->UnloadFont(); - mXFont = nsnull; - ::gdk_font_unref(gdkFont); - mFontHolder = nsnull; - return; - } -} - mFont = gdkFont; - -#ifdef NS_FONT_DEBUG_LOAD_FONT - if (gFontDebug & NS_FONT_DEBUG_LOAD_FONT) { - printf("loaded %s\n", mName); - } -#endif - - } - -#ifdef NS_FONT_DEBUG_LOAD_FONT - else if (gFontDebug & NS_FONT_DEBUG_LOAD_FONT) { - printf("cannot load %s\n", mName); - } -#endif - -} - -GdkFont* -nsFontGTK::GetGDKFont(void) -{ - return mFont; -} - -nsXFont* -nsFontGTK::GetXFont(void) -{ - return mXFont; -} - -PRBool -nsFontGTK::GetXFontIs10646(void) -{ - return ((PRBool) (mCharSetInfo == &ISO106461)); -} - -PRBool -nsFontGTK::IsFreeTypeFont(void) -{ - return PR_FALSE; -} - -nsFontGTK::nsFontGTK() -{ - MOZ_COUNT_CTOR(nsFontGTK); -} - -nsFontGTK::~nsFontGTK() -{ - MOZ_COUNT_DTOR(nsFontGTK); - if (mXFont) { - delete mXFont; - } - if (mFont && (mAABaseSize==0)) { - gdk_font_unref(mFont); - } - if (mCharSetInfo == &ISO106461) { - FreeCCMap(mCCMap); - } - if (mName) { - PR_smprintf_free(mName); - } -} - -class nsFontGTKNormal : public nsFontGTK -{ -public: - nsFontGTKNormal(); - nsFontGTKNormal(nsFontGTK*); - virtual ~nsFontGTKNormal(); - - virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength); - virtual gint DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength); -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); -#endif -}; - -nsFontGTKNormal::nsFontGTKNormal() -{ - mFontHolder = nsnull; -} - -nsFontGTKNormal::nsFontGTKNormal(nsFontGTK *aFont) -{ - mAABaseSize = aFont->mSize; - mFontHolder = aFont->GetGDKFont(); - if (!mFontHolder) { - aFont->LoadFont(); - mFontHolder = aFont->GetGDKFont(); - } - NS_ASSERTION(mFontHolder, "font to copy not loaded"); - if (mFontHolder) - ::gdk_font_ref(mFontHolder); -} - -nsFontGTKNormal::~nsFontGTKNormal() -{ - if (mFontHolder) - ::gdk_font_unref(mFontHolder); -} - -gint -nsFontGTKNormal::GetWidth(const PRUnichar* aString, PRUint32 aLength) -{ - if (!mFont) { - LoadFont(); - if (!mFont) { - return 0; - } - } - - XChar2b buf[512]; - char* p; - PRInt32 bufLen; - ENCODER_BUFFER_ALLOC_IF_NEEDED(p, mCharSetInfo->mConverter, - aString, aLength, buf, sizeof(buf), bufLen); - gint len = mCharSetInfo->Convert(mCharSetInfo, mXFont->GetXFontStruct(), - aString, aLength, p, bufLen); - gint outWidth; - if (mXFont->IsSingleByte()) - outWidth = mXFont->TextWidth8(p, len); - else - outWidth = mXFont->TextWidth16((const XChar2b*)p, len/2); - ENCODER_BUFFER_FREE_IF_NEEDED(p, buf); - return outWidth; -} - -gint -nsFontGTKNormal::DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, - nscoord aX, nscoord aY, - const PRUnichar* aString, PRUint32 aLength) -{ - if (!mFont) { - LoadFont(); - if (!mFont) { - return 0; - } - } - - XChar2b buf[512]; - char* p; - PRInt32 bufLen; - ENCODER_BUFFER_ALLOC_IF_NEEDED(p, mCharSetInfo->mConverter, - aString, aLength, buf, sizeof(buf), bufLen); - gint len = mCharSetInfo->Convert(mCharSetInfo, mXFont->GetXFontStruct(), - aString, aLength, p, bufLen); - GdkGC *gc = aContext->GetGC(); - gint outWidth; - if (mXFont->IsSingleByte()) { - mXFont->DrawText8(aSurface->GetDrawable(), gc, aX, - aY + mBaselineAdjust, p, len); - outWidth = mXFont->TextWidth8(p, len); - } - else { - mXFont->DrawText16(aSurface->GetDrawable(), gc, aX, aY + mBaselineAdjust, - (const XChar2b*)p, len/2); - outWidth = mXFont->TextWidth16((const XChar2b*)p, len/2); - } - gdk_gc_unref(gc); - ENCODER_BUFFER_FREE_IF_NEEDED(p, buf); - return outWidth; -} - -#ifdef MOZ_MATHML -// bounding metrics for a string -// remember returned values are not in app units -nsresult -nsFontGTKNormal::GetBoundingMetrics (const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - aBoundingMetrics.Clear(); - - if (!mFont) { - LoadFont(); - if (!mFont) { - return NS_ERROR_FAILURE; - } - } - - if (aString && 0 < aLength) { - XFontStruct *fontInfo = mXFont->GetXFontStruct(); - XChar2b buf[512]; - char* p; - PRInt32 bufLen; - ENCODER_BUFFER_ALLOC_IF_NEEDED(p, mCharSetInfo->mConverter, - aString, aLength, buf, sizeof(buf), bufLen); - gint len = mCharSetInfo->Convert(mCharSetInfo, fontInfo, aString, aLength, - p, bufLen); - if (mXFont->IsSingleByte()) { - mXFont->TextExtents8(p, len, - &aBoundingMetrics.leftBearing, - &aBoundingMetrics.rightBearing, - &aBoundingMetrics.width, - &aBoundingMetrics.ascent, - &aBoundingMetrics.descent); - } - else { - mXFont->TextExtents16((const XChar2b*)p, len, - &aBoundingMetrics.leftBearing, - &aBoundingMetrics.rightBearing, - &aBoundingMetrics.width, - &aBoundingMetrics.ascent, - &aBoundingMetrics.descent); - } - ENCODER_BUFFER_FREE_IF_NEEDED(p, buf); - } - - return NS_OK; -} -#endif - -class nsFontGTKSubstitute : public nsFontGTK -{ -public: - nsFontGTKSubstitute(nsFontGTK* aFont); - virtual ~nsFontGTKSubstitute(); - - virtual GdkFont* GetGDKFont(void); - virtual nsXFont* GetXFont(void); - virtual PRBool GetXFontIs10646(void); - virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength); - virtual gint DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength); -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); -#endif - virtual PRUint32 Convert(const PRUnichar* aSrc, PRUint32 aSrcLen, - PRUnichar* aDest, PRUint32 aDestLen); - - nsFontGTK* mSubstituteFont; -}; - -nsFontGTKSubstitute::nsFontGTKSubstitute(nsFontGTK* aFont) -{ - mSubstituteFont = aFont; -} - -nsFontGTKSubstitute::~nsFontGTKSubstitute() -{ - // Do not free mSubstituteFont here. It is owned by somebody else. -} - -PRUint32 -nsFontGTKSubstitute::Convert(const PRUnichar* aSrc, PRUint32 aSrcLen, - PRUnichar* aDest, PRUint32 aDestLen) -{ - nsresult res; - if (!gFontSubConverter) { - CallCreateInstance(NS_SAVEASCHARSET_CONTRACTID, &gFontSubConverter); - if (gFontSubConverter) { - res = gFontSubConverter->Init("ISO-8859-1", - nsISaveAsCharset::attr_FallbackQuestionMark + - nsISaveAsCharset::attr_EntityAfterCharsetConv + - nsISaveAsCharset::attr_IgnoreIgnorables, - nsIEntityConverter::transliterate); - if (NS_FAILED(res)) { - NS_RELEASE(gFontSubConverter); - } - } - } - - if (gFontSubConverter) { - nsAutoString tmp(aSrc, aSrcLen); - char* conv = nsnull; - res = gFontSubConverter->Convert(tmp.get(), &conv); - if (NS_SUCCEEDED(res) && conv) { - char* p = conv; - PRUint32 i; - for (i = 0; i < aDestLen; i++) { - if (*p) { - aDest[i] = *p; - } - else { - break; - } - p++; - } - nsMemory::Free(conv); - conv = nsnull; - return i; - } - } - - if (aSrcLen > aDestLen) { - aSrcLen = aDestLen; - } - for (PRUint32 i = 0; i < aSrcLen; i++) { - aDest[i] = '?'; - } - - return aSrcLen; -} - -gint -nsFontGTKSubstitute::GetWidth(const PRUnichar* aString, PRUint32 aLength) -{ - PRUnichar buf[512]; - PRUnichar *p = buf; - PRUint32 bufLen = sizeof(buf)/sizeof(PRUnichar); - if ((aLength*2) > bufLen) { - PRUnichar *tmp; - tmp = (PRUnichar*)nsMemory::Alloc(sizeof(PRUnichar) * (aLength*2)); - if (tmp) { - p = tmp; - bufLen = (aLength*2); - } - } - PRUint32 len = Convert(aString, aLength, p, bufLen); - gint outWidth = mSubstituteFont->GetWidth(p, len); - if (p != buf) - nsMemory::Free(p); - return outWidth; - -} - -gint -nsFontGTKSubstitute::DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, - nscoord aX, nscoord aY, - const PRUnichar* aString, PRUint32 aLength) -{ - PRUnichar buf[512]; - PRUnichar *p = buf; - PRUint32 bufLen = sizeof(buf)/sizeof(PRUnichar); - if ((aLength*2) > bufLen) { - PRUnichar *tmp; - tmp = (PRUnichar*)nsMemory::Alloc(sizeof(PRUnichar) * (aLength*2)); - if (tmp) { - p = tmp; - bufLen = (aLength*2); - } - } - PRUint32 len = Convert(aString, aLength, p, bufLen); - gint outWidth = mSubstituteFont->DrawString(aContext, aSurface, - aX, aY, p, len); - if (p != buf) - nsMemory::Free(p); - return outWidth; -} - -#ifdef MOZ_MATHML -// bounding metrics for a string -// remember returned values are not in app units -nsresult -nsFontGTKSubstitute::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - PRUnichar buf[512]; - PRUnichar *p = buf; - PRUint32 bufLen = sizeof(buf)/sizeof(PRUnichar); - if ((aLength*2) > bufLen) { - PRUnichar *tmp; - tmp = (PRUnichar*)nsMemory::Alloc(sizeof(PRUnichar) * (aLength*2)); - if (tmp) { - p = tmp; - bufLen = (aLength*2); - } - } - PRUint32 len = Convert(aString, aLength, p, bufLen); - nsresult res = mSubstituteFont->GetBoundingMetrics(p, len, - aBoundingMetrics); - if (p != buf) - nsMemory::Free(p); - return res; -} -#endif - -GdkFont* -nsFontGTKSubstitute::GetGDKFont(void) -{ - return mSubstituteFont->GetGDKFont(); -} - -nsXFont* -nsFontGTKSubstitute::GetXFont(void) -{ - return mSubstituteFont->GetXFont(); -} - -PRBool -nsFontGTKSubstitute::GetXFontIs10646(void) -{ - return mSubstituteFont->GetXFontIs10646(); -} - -class nsFontGTKUserDefined : public nsFontGTK -{ -public: - nsFontGTKUserDefined(); - virtual ~nsFontGTKUserDefined(); - - virtual PRBool Init(nsFontGTK* aFont); - virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength); - virtual gint DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength); -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); -#endif - virtual PRUint32 Convert(const PRUnichar* aSrc, PRInt32 aSrcLen, - char* aDest, PRInt32 aDestLen); -}; - -nsFontGTKUserDefined::nsFontGTKUserDefined() -{ -} - -nsFontGTKUserDefined::~nsFontGTKUserDefined() -{ - // Do not free mFont here. It is owned by somebody else. -} - -PRBool -nsFontGTKUserDefined::Init(nsFontGTK* aFont) -{ - if (!aFont->GetXFont()) { - aFont->LoadFont(); - if (!aFont->GetXFont()) { - mCCMap = gEmptyCCMap; - return PR_FALSE; - } - } - mXFont = aFont->GetXFont(); - mCCMap = gUserDefinedCCMap; - mName = aFont->mName; - - return PR_TRUE; -} - -PRUint32 -nsFontGTKUserDefined::Convert(const PRUnichar* aSrc, PRInt32 aSrcLen, - char* aDest, PRInt32 aDestLen) -{ - if (aSrcLen > aDestLen) { - aSrcLen = aDestLen; - } - gUserDefinedConverter->Convert(aSrc, &aSrcLen, aDest, &aDestLen); - - return aSrcLen; -} - -gint -nsFontGTKUserDefined::GetWidth(const PRUnichar* aString, PRUint32 aLength) -{ - char buf[1024]; - char* p; - PRInt32 bufLen; - ENCODER_BUFFER_ALLOC_IF_NEEDED(p, gUserDefinedConverter, - aString, aLength, buf, sizeof(buf), bufLen); - PRUint32 len = Convert(aString, aLength, p, bufLen); - - gint outWidth; - if (mXFont->IsSingleByte()) - outWidth = mXFont->TextWidth8(p, len); - else - outWidth = mXFont->TextWidth16((const XChar2b*)p, len/2); - ENCODER_BUFFER_FREE_IF_NEEDED(p, buf); - return outWidth; -} - -gint -nsFontGTKUserDefined::DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, - nscoord aX, nscoord aY, - const PRUnichar* aString, PRUint32 aLength) -{ - char buf[1024]; - char* p; - PRInt32 bufLen; - ENCODER_BUFFER_ALLOC_IF_NEEDED(p, gUserDefinedConverter, - aString, aLength, buf, sizeof(buf), bufLen); - PRUint32 len = Convert(aString, aLength, p, bufLen); - GdkGC *gc = aContext->GetGC(); - - gint outWidth; - if (mXFont->IsSingleByte()) { - mXFont->DrawText8(aSurface->GetDrawable(), gc, aX, - aY + mBaselineAdjust, p, len); - outWidth = mXFont->TextWidth8(p, len); - } - else { - mXFont->DrawText16(aSurface->GetDrawable(), gc, aX, aY + mBaselineAdjust, - (const XChar2b*)p, len); - outWidth = mXFont->TextWidth16((const XChar2b*)p, len/2); - } - gdk_gc_unref(gc); - ENCODER_BUFFER_FREE_IF_NEEDED(p, buf); - return outWidth; -} - -#ifdef MOZ_MATHML -// bounding metrics for a string -// remember returned values are not in app units -nsresult -nsFontGTKUserDefined::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - aBoundingMetrics.Clear(); - - if (aString && 0 < aLength) { - char buf[1024]; - char* p; - PRInt32 bufLen; - ENCODER_BUFFER_ALLOC_IF_NEEDED(p, gUserDefinedConverter, - aString, aLength, buf, sizeof(buf), bufLen); - PRUint32 len = Convert(aString, aLength, p, bufLen); - if (mXFont->IsSingleByte()) { - mXFont->TextExtents8(p, len, - &aBoundingMetrics.leftBearing, - &aBoundingMetrics.rightBearing, - &aBoundingMetrics.width, - &aBoundingMetrics.ascent, - &aBoundingMetrics.descent); - } - else { - mXFont->TextExtents16((const XChar2b*)p, len, - &aBoundingMetrics.leftBearing, - &aBoundingMetrics.rightBearing, - &aBoundingMetrics.width, - &aBoundingMetrics.ascent, - &aBoundingMetrics.descent); - } - ENCODER_BUFFER_FREE_IF_NEEDED(p, buf); - } - - return NS_OK; -} -#endif - -nsFontGTK* -nsFontMetricsGTK::AddToLoadedFontsList(nsFontGTK* aFont) -{ - if (mLoadedFontsCount == mLoadedFontsAlloc) { - int newSize; - if (mLoadedFontsAlloc) { - newSize = (2 * mLoadedFontsAlloc); - } - else { - newSize = 1; - } - nsFontGTK** newPointer = (nsFontGTK**) - PR_Realloc(mLoadedFonts, newSize * sizeof(nsFontGTK*)); - if (newPointer) { - mLoadedFonts = newPointer; - mLoadedFontsAlloc = newSize; - } - else { - return nsnull; - } - } - mLoadedFonts[mLoadedFontsCount++] = aFont; - return aFont; -} - -// define a size such that a scaled font would always be closer -// to the desired size than this -#define NOT_FOUND_FONT_SIZE 1000*1000*1000 - -nsFontGTK* -nsFontMetricsGTK::FindNearestSize(nsFontStretch* aStretch, PRUint16 aSize) -{ - nsFontGTK* font = nsnull; - if (aStretch->mSizes) { - nsFontGTK** begin = aStretch->mSizes; - nsFontGTK** end = &aStretch->mSizes[aStretch->mSizesCount]; - nsFontGTK** s; - // scan the list of sizes - for (s = begin; s < end; s++) { - // stop when we hit or overshoot the size - if ((*s)->mSize >= aSize) { - break; - } - } - // backup if we hit the end of the list - if (s == end) { - s--; - } - else if (s != begin) { - // if we overshot pick the closest size - if (((*s)->mSize - aSize) >= (aSize - (*(s - 1))->mSize)) { - s--; - } - } - // this is the nearest bitmap font - font = *s; - } - return font; -} - -static PRBool -SetFontCharsetInfo(nsFontGTK *aFont, nsFontCharSetInfo* aCharSet, - PRUint32 aChar) -{ - if (aCharSet->mCharSet) { - aFont->mCCMap = aCharSet->mCCMap; - // check that the font is not empty - if (CCMAP_HAS_CHAR_EXT(aFont->mCCMap, aChar)) { - aFont->LoadFont(); - if (!aFont->GetXFont()) { - return PR_FALSE; - } - } - } - else { - if (aCharSet == &ISO106461) { - aFont->LoadFont(); - if (!aFont->GetXFont()) { - return PR_FALSE; - } - } - } - return PR_TRUE; -} - -static nsFontGTK* -SetupUserDefinedFont(nsFontGTK *aFont) -{ - if (!aFont->mUserDefinedFont) { - aFont->mUserDefinedFont = new nsFontGTKUserDefined(); - if (!aFont->mUserDefinedFont) { - return nsnull; - } - if (!aFont->mUserDefinedFont->Init(aFont)) { - return nsnull; - } - } - return aFont->mUserDefinedFont; -} - - -nsFontGTK* -nsFontMetricsGTK::GetAASBBaseFont(nsFontStretch* aStretch, - nsFontCharSetInfo* aCharSet) -{ - nsFontGTK* base_aafont; - PRInt32 scale_size; - PRUint32 aa_target_size; - - scale_size = PR_MAX(mPixelSize, aCharSet->mAABitmapScaleMin); - aa_target_size = MAX((scale_size*2), 16); - base_aafont = FindNearestSize(aStretch, aa_target_size); - NS_ASSERTION(base_aafont, - "failed to find a base font for Anti-Aliased bitmap Scaling"); - return base_aafont; -} - -nsFontGTK* -nsFontMetricsGTK::PickASizeAndLoad(nsFontStretch* aStretch, - nsFontCharSetInfo* aCharSet, PRUint32 aChar, const char *aName) -{ - -#ifdef MOZ_ENABLE_FREETYPE2 - if (aStretch->mFreeTypeFaceID) { - //FREETYPE_FONT_PRINTF(("mFreeTypeFaceID = 0x%p", aStretch->mFreeTypeFaceID)); - nsFreeTypeFont *ftfont = nsFreeTypeFont::NewFont(aStretch->mFreeTypeFaceID, - mPixelSize, - aName); - if (!ftfont) { - FREETYPE_FONT_PRINTF(("failed to create font")); - return nsnull; - } - //FREETYPE_FONT_PRINTF(("created ftfont")); - /* - * XXX Instead of passing pixel size, we ought to take underline - * into account. (Extra space for underline for Asian fonts.) - */ - ftfont->mName = PR_smprintf("%s", aName); - if (!ftfont->mName) { - FREETYPE_FONT_PRINTF(("failed to create mName")); - delete ftfont; - return nsnull; - } - SetCharsetLangGroup(aCharSet); - ftfont->mSize = mPixelSize; - ftfont->LoadFont(); - ftfont->mCharSetInfo = &ISO106461; - //FREETYPE_FONT_PRINTF(("add the ftfont")); - return AddToLoadedFontsList(ftfont); - } - - if (!IS_IN_BMP(aChar)) { - // Non-BMP is only supported by FreeType - return nsnull; - } -#endif - - PRBool use_scaled_font = PR_FALSE; - PRBool have_nearly_rightsized_bitmap = PR_FALSE; - nsFontGTK* base_aafont = nsnull; - - PRInt32 bitmap_size = NOT_FOUND_FONT_SIZE; - PRInt32 scale_size = mPixelSize; - nsFontGTK* font = FindNearestSize(aStretch, mPixelSize); - if (font) { - bitmap_size = font->mSize; - if ( (bitmap_size >= mPixelSize-(mPixelSize/10)) - && (bitmap_size <= mPixelSize+(mPixelSize/10))) - // When the size of a hand tuned font is close to the desired size - // favor it over outline scaled font - have_nearly_rightsized_bitmap = PR_TRUE; - } - - // - // If the user says always try to aasb (anti alias scaled bitmap) scale - // - if (gAABitmapScaleEnabled && aCharSet->mAABitmapScaleAlways) { - base_aafont = GetAASBBaseFont(aStretch, aCharSet); - if (base_aafont) { - use_scaled_font = PR_TRUE; - SIZE_FONT_PRINTF(("anti-aliased bitmap scaled font: %s\n" - " desired=%d, aa-scaled=%d, bitmap=%d, " - "aa_bitmap=%d", - aName, mPixelSize, scale_size, bitmap_size, base_aafont->mSize)); - } - } - - // - // if not already aasb scaling and - // if we do not have a bitmap that is nearly the correct size - // - if (!use_scaled_font && !have_nearly_rightsized_bitmap) { - // check if we can use an outline scaled font - if (aStretch->mOutlineScaled) { - scale_size = PR_MAX(mPixelSize, aCharSet->mOutlineScaleMin); - - if (PR_ABS(mPixelSize-scale_size) < PR_ABS(mPixelSize-bitmap_size)) { - use_scaled_font = 1; - SIZE_FONT_PRINTF(("outline font:______ %s\n" - " desired=%d, scaled=%d, bitmap=%d", - aStretch->mScalable, mPixelSize, scale_size, - (bitmap_size=NOT_FOUND_FONT_SIZE?0:bitmap_size))); - } - } - // see if we can aasb (anti alias scaled bitmap) - if (!use_scaled_font - && (bitmap_sizemAABitmapScaleMin); - double ratio = (bitmap_size / ((double) mPixelSize)); - if ( (ratio < aCharSet->mAABitmapUndersize) - || (ratio > aCharSet->mAABitmapOversize)) { - // - // Try to get a size font to scale that is 2x larger - // (but at least 16 pixel) - // - base_aafont = GetAASBBaseFont(aStretch, aCharSet); - if (base_aafont) { - use_scaled_font = PR_TRUE; - SIZE_FONT_PRINTF(("anti-aliased bitmap scaled font: %s\n" - " desired=%d, aa-scaled=%d, bitmap=%d, " - "aa_bitmap=%d", - aName, mPixelSize, scale_size, bitmap_size, base_aafont->mSize)); - } - } - } - // last resort: consider a bitmap scaled font (ugly!) - if (!use_scaled_font && aStretch->mScalable) { - scale_size = PR_MAX(mPixelSize, aCharSet->mBitmapScaleMin); - double ratio = (bitmap_size / ((double) mPixelSize)); - if ((ratio < aCharSet->mBitmapUndersize) - || (ratio > aCharSet->mBitmapOversize)) { - if ((PR_ABS(mPixelSize-scale_size) < PR_ABS(mPixelSize-bitmap_size))) { - use_scaled_font = 1; - SIZE_FONT_PRINTF(("bitmap scaled font: %s\n" - " desired=%d, scaled=%d, bitmap=%d", - aStretch->mScalable, mPixelSize, scale_size, - (bitmap_size=NOT_FOUND_FONT_SIZE?0:bitmap_size))); - } - } - } - } - - NS_ASSERTION((bitmap_sizemScaledFonts.Count(); - nsFontGTK* p = nsnull; - for (i = 0; i < n; i++) { - p = (nsFontGTK*) aStretch->mScaledFonts.ElementAt(i); - if (p->mSize == scale_size) { - break; - } - } - if (i == n) { - if (base_aafont) { - // setup the base font - if (!SetFontCharsetInfo(base_aafont, aCharSet, aChar)) - return nsnull; - if (mIsUserDefined) { - base_aafont = SetupUserDefinedFont(base_aafont); - if (!base_aafont) - return nsnull; - } - font = new nsFontGTKNormal(base_aafont); - } - else - font = new nsFontGTKNormal; - if (font) { - /* - * XXX Instead of passing pixel size, we ought to take underline - * into account. (Extra space for underline for Asian fonts.) - */ - if (base_aafont) { - font->mName = PR_smprintf("%s", base_aafont->mName); - font->mAABaseSize = base_aafont->mSize; - } - else { - font->mName = PR_smprintf(aStretch->mScalable, scale_size); - font->mAABaseSize = 0; - } - if (!font->mName) { - delete font; - return nsnull; - } - font->mSize = scale_size; - font->mCharSetInfo = aCharSet; - aStretch->mScaledFonts.AppendElement(font); - } - else { - return nsnull; - } - } - else { - font = p; - } - } - - if (!SetFontCharsetInfo(font, aCharSet, aChar)) - return nsnull; - - if (mIsUserDefined) { - font = SetupUserDefinedFont(font); - if (!font) - return nsnull; - } - - return AddToLoadedFontsList(font); -} - -nsresult -nsFontMetricsGTK::GetWidth (const char* aString, PRUint32 aLength, - nscoord& aWidth, - nsRenderingContextGTK *aContext) -{ - if (aLength == 0) { - aWidth = 0; - return NS_OK; - } - - nsXFont *xFont = mCurrentFont->GetXFont(); - gint rawWidth; - - if (mCurrentFont->IsFreeTypeFont()) { - // this function is only supposed to be called for ascii data - rawWidth = mCurrentFont-> - GetWidth(NS_ConvertASCIItoUTF16(aString, aLength).get(), aLength); - } - else if (!mCurrentFont->GetXFontIs10646()) { - NS_ASSERTION(xFont->IsSingleByte(),"wrong string/font size"); - // 8 bit data with an 8 bit font - rawWidth = xFont->TextWidth8(aString, aLength); - } - else { - NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size"); - // we have 8 bit data but a 16 bit font - rawWidth = Widen8To16AndGetWidth (mCurrentFont->GetXFont(), - aString, aLength); - } - - float f; - f = mDeviceContext->DevUnitsToAppUnits(); - aWidth = NSToCoordRound(rawWidth * f); - - return NS_OK; -} - -nsresult -nsFontMetricsGTK::GetWidth (const PRUnichar* aString, PRUint32 aLength, - nscoord& aWidth, PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - if (aLength == 0) { - aWidth = 0; - return NS_OK; - } - - nsFontGTK* prevFont = nsnull; - gint rawWidth = 0; - PRUint32 start = 0; - PRUint32 i; - - PRUint32 extraSurrogateLength; - for (i = 0; i < aLength; i+=1+extraSurrogateLength) { - PRUint32 c = aString[i]; - extraSurrogateLength=0; - - if(i < aLength-1 && NS_IS_HIGH_SURROGATE(c) && NS_IS_LOW_SURROGATE(aString[i+1])) { - // if surrogate, make UCS4 code point from high aString[i] and - // low surrogate aString[i+1] - c = SURROGATE_TO_UCS4(c, aString[i+1]); - - // skip aString[i+1], it is already used as low surrogate - extraSurrogateLength = 1; - } - nsFontGTK* currFont = nsnull; - nsFontGTK** font = mLoadedFonts; - nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount]; - while (font < end) { - if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) { - currFont = *font; - goto FoundFont; // for speed -- avoid "if" statement - } - font++; - } - currFont = FindFont(c); - FoundFont: - // XXX avoid this test by duplicating code -- erik - if (prevFont) { - if (currFont != prevFont) { - rawWidth += prevFont->GetWidth(&aString[start], i - start); - prevFont = currFont; - start = i; - } - } - else { - prevFont = currFont; - start = i; - } - } - - if (prevFont) { - rawWidth += prevFont->GetWidth(&aString[start], i - start); - } - - float f; - f = mDeviceContext->DevUnitsToAppUnits(); - aWidth = NSToCoordRound(rawWidth * f); - - if (nsnull != aFontID) - *aFontID = 0; - - return NS_OK; -} - -nsresult -nsFontMetricsGTK::DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface) -{ - if (!aLength) - return NS_ERROR_FAILURE; - - nsresult rv = NS_OK; - - g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mCurrentFont != NULL, NS_ERROR_FAILURE); - - nscoord x = aX; - nscoord y = aY; - - aContext->UpdateGC(); - - nsXFont *xFont = mCurrentFont->GetXFont(); - - // Get the gc - note that we have to unref this later - GdkGC *gc = aContext->GetGC(); - - if (nsnull != aSpacing) { - // Render the string, one character at a time... - const char* end = aString + aLength; - - while (aString < end) { - char ch = *aString++; - nscoord xx = x; - nscoord yy = y; - aContext->GetTranMatrix()->TransformCoord(&xx, &yy); - - if (mCurrentFont->IsFreeTypeFont()) { - // this function is only supposed to be called for ascii data - rv = mCurrentFont->DrawString(aContext, aSurface, xx, yy, - NS_ConvertASCIItoUTF16(aString, aLength).get(), - aLength); - } - else if (!mCurrentFont->GetXFontIs10646()) { - // 8 bit data with an 8 bit font - NS_ASSERTION(xFont->IsSingleByte(),"wrong string/font size"); - xFont->DrawText8(aSurface->GetDrawable(), gc, xx, yy, &ch, 1); - } - else { - // we have 8 bit data but a 16 bit font - NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size"); - Widen8To16AndDraw(aSurface->GetDrawable(), xFont, gc, - xx, yy, &ch, 1); - } - - x += *aSpacing++; - } - } - else { - aContext->GetTranMatrix()->TransformCoord(&x, &y); - - if (mCurrentFont->IsFreeTypeFont()) { - // this function is only supposed to be called for ascii data - rv = mCurrentFont->DrawString(aContext, aSurface, x, y, - NS_ConvertASCIItoUTF16(aString, aLength).get(), - aLength); - } - else if (!mCurrentFont->GetXFontIs10646()) { // keep 8 bit path fast - // 8 bit data with an 8 bit font - NS_ASSERTION(xFont->IsSingleByte(),"wrong string/font size"); - xFont->DrawText8(aSurface->GetDrawable(), gc, - x, y, aString, aLength); - } - else { - // we have 8 bit data but a 16 bit font - NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size"); - Widen8To16AndDraw(aSurface->GetDrawable(), xFont, gc, - x, y, aString, aLength); - } - } - - gdk_gc_unref(gc); - - return rv; -} - -nsresult -nsFontMetricsGTK::DrawString(const PRUnichar* aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface) -{ - if (!aLength) - return NS_ERROR_FAILURE; - - g_return_val_if_fail(aSurface != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE); - - nscoord x = aX; - nscoord y = aY; - - aContext->GetTranMatrix()->TransformCoord(&x, &y); - - nsFontGTK* prevFont = nsnull; - PRUint32 start = 0; - PRUint32 i; - - PRUint32 extraSurrogateLength; - for (i = 0; i < aLength; i+=1+extraSurrogateLength) { - PRUint32 c = aString[i]; - extraSurrogateLength=0; - if(i < aLength-1 && NS_IS_HIGH_SURROGATE(c) && NS_IS_LOW_SURROGATE(aString[i+1])) { - // if surrogate, make UCS4 code point from high aString[i] and - // low surrogate aString[i+1] - c = SURROGATE_TO_UCS4(c, aString[i+1]); - - // skip aString[i+1], it is already used as low surrogate - extraSurrogateLength = 1; - } - nsFontGTK* currFont = nsnull; - nsFontGTK** font = mLoadedFonts; - nsFontGTK** lastFont = &mLoadedFonts[mLoadedFontsCount]; - while (font < lastFont) { - if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) { - currFont = *font; - goto FoundFont; // for speed -- avoid "if" statement - } - font++; - } - - currFont = FindFont(c); - - FoundFont: - // XXX avoid this test by duplicating code -- erik - if (prevFont) { - if (currFont != prevFont) { - if (aSpacing) { - const PRUnichar* str = &aString[start]; - const PRUnichar* end = &aString[i]; - - // save off mCurrentFont and set it so that we - // cache the GC's font correctly - nsFontGTK *oldFont = mCurrentFont; - mCurrentFont = prevFont; - aContext->UpdateGC(); - - while (str < end) { - x = aX; - y = aY; - aContext->GetTranMatrix()->TransformCoord(&x, &y); - prevFont->DrawString(aContext, aSurface, x, y, str, 1); - aX += *aSpacing++; - str++; - } - - mCurrentFont = oldFont; - } - else { - nsFontGTK *oldFont = mCurrentFont; - mCurrentFont = prevFont; - aContext->UpdateGC(); - - x += prevFont->DrawString(aContext, aSurface, - x, y, &aString[start], - i - start); - - mCurrentFont = oldFont; - } - - prevFont = currFont; - start = i; - } - } - else { - prevFont = currFont; - start = i; - } - } - - if (prevFont) { - nsFontGTK *oldFont = mCurrentFont; - mCurrentFont = prevFont; - aContext->UpdateGC(); - - if (aSpacing) { - const PRUnichar* str = &aString[start]; - const PRUnichar* end = &aString[i]; - - while (str < end) { - x = aX; - y = aY; - aContext->GetTranMatrix()->TransformCoord(&x, &y); - prevFont->DrawString(aContext, aSurface, x, y, str, 1); - aX += *aSpacing++; - str++; - } - } - else { - prevFont->DrawString(aContext, aSurface, x, y, - &aString[start], i - start); - } - - mCurrentFont = oldFont; - } - - return NS_OK; -} - -#ifdef MOZ_MATHML - -nsresult -nsFontMetricsGTK::GetBoundingMetrics(const char *aString, PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - nsRenderingContextGTK *aContext) -{ - aBoundingMetrics.Clear(); - - if (!aString || !aLength) - return NS_ERROR_FAILURE; - - nsresult rv = NS_OK; - - nsXFont *xFont = mCurrentFont->GetXFont(); - - if (mCurrentFont->IsFreeTypeFont()) { - // this function is only supposed to be called for ascii data - rv = mCurrentFont->GetBoundingMetrics( - NS_ConvertASCIItoUTF16(aString, aLength).get(), - aLength, aBoundingMetrics); - } - else if (!mCurrentFont->GetXFontIs10646()) { - // 8 bit data with an 8 bit font - NS_ASSERTION(xFont->IsSingleByte(),"wrong string/font size"); - xFont->TextExtents8(aString, aLength, - &aBoundingMetrics.leftBearing, - &aBoundingMetrics.rightBearing, - &aBoundingMetrics.width, - &aBoundingMetrics.ascent, - &aBoundingMetrics.descent); - } - else { - // we have 8 bit data but a 16 bit font - NS_ASSERTION(!xFont->IsSingleByte(),"wrong string/font size"); - Widen8To16AndGetTextExtents (mCurrentFont->GetXFont(), - aString, aLength, - &aBoundingMetrics.leftBearing, - &aBoundingMetrics.rightBearing, - &aBoundingMetrics.width, - &aBoundingMetrics.ascent, - &aBoundingMetrics.descent); - } - - float P2T; - P2T = mDeviceContext->DevUnitsToAppUnits(); - - aBoundingMetrics.leftBearing = - NSToCoordRound(aBoundingMetrics.leftBearing * P2T); - aBoundingMetrics.rightBearing = - NSToCoordRound(aBoundingMetrics.rightBearing * P2T); - aBoundingMetrics.width = NSToCoordRound(aBoundingMetrics.width * P2T); - aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T); - aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T); - - return rv; -} - -nsresult -nsFontMetricsGTK::GetBoundingMetrics(const PRUnichar *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - PRInt32 *aFontID, - nsRenderingContextGTK *aContext) -{ - aBoundingMetrics.Clear(); - - if (!aString || !aLength) - return NS_ERROR_FAILURE; - - nsFontGTK* prevFont = nsnull; - - nsBoundingMetrics rawbm; - PRBool firstTime = PR_TRUE; - PRUint32 start = 0; - PRUint32 i; - PRUint32 extraSurrogateLength; - for (i = 0; i < aLength; i+=1+extraSurrogateLength) { - PRUint32 c = aString[i]; - extraSurrogateLength=0; - if(i < aLength-1 && NS_IS_HIGH_SURROGATE(c) && NS_IS_LOW_SURROGATE(aString[i+1])) { - // if surrogate, make UCS4 code point from high aString[i] and - // low surrogate aString[i+1] - c = SURROGATE_TO_UCS4(c, aString[i+1]); - - // skip aString[i+1], it is already used as low surrogate - extraSurrogateLength = 1; - } - nsFontGTK* currFont = nsnull; - nsFontGTK** font = mLoadedFonts; - nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount]; - - while (font < end) { - if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) { - currFont = *font; - goto FoundFont; // for speed -- avoid "if" statement - } - font++; - } - currFont = FindFont(c); - - FoundFont: - // XXX avoid this test by duplicating code -- erik - if (prevFont) { - if (currFont != prevFont) { - prevFont->GetBoundingMetrics((const PRUnichar*)&aString[start], - i - start, rawbm); - if (firstTime) { - firstTime = PR_FALSE; - aBoundingMetrics = rawbm; - } - else { - aBoundingMetrics += rawbm; - } - prevFont = currFont; - start = i; - } - } - else { - prevFont = currFont; - start = i; - } - } - - if (prevFont) { - prevFont->GetBoundingMetrics((const PRUnichar*) &aString[start], - i - start, rawbm); - if (firstTime) - aBoundingMetrics = rawbm; - else - aBoundingMetrics += rawbm; - } - - // convert to app units - float P2T; - P2T = mDeviceContext->DevUnitsToAppUnits(); - - aBoundingMetrics.leftBearing = - NSToCoordRound(aBoundingMetrics.leftBearing * P2T); - aBoundingMetrics.rightBearing = - NSToCoordRound(aBoundingMetrics.rightBearing * P2T); - aBoundingMetrics.width = NSToCoordRound(aBoundingMetrics.width * P2T); - aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T); - aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T); - - if (nsnull != aFontID) - *aFontID = 0; - - return NS_OK; -} - -#endif /* MOZ_MATHML */ - -nsresult -nsFontMetricsGTK::GetTextDimensions (const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - aDimensions.Clear(); - - if (!aString || !aLength) - return NS_ERROR_FAILURE; - - nsFontGTK* prevFont = nsnull; - gint rawWidth = 0, rawAscent = 0, rawDescent = 0; - PRUint32 start = 0; - PRUint32 i; - - PRUint32 extraSurrogateLength; - for (i = 0; i < aLength; i+=1+extraSurrogateLength) { - PRUint32 c = aString[i]; - extraSurrogateLength=0; - if(i < aLength-1 && NS_IS_HIGH_SURROGATE(c) && NS_IS_LOW_SURROGATE(aString[i+1])) { - // if surrogate, make UCS4 code point from high aString[i] and - // low surrogate aString[i+1] - c = SURROGATE_TO_UCS4(c, aString[i+1]); - - // skip aString[i+1], it is already used as low surrogate - extraSurrogateLength = 1; - } - nsFontGTK* currFont = nsnull; - nsFontGTK** font = mLoadedFonts; - nsFontGTK** end = &mLoadedFonts[mLoadedFontsCount]; - - while (font < end) { - if (CCMAP_HAS_CHAR_EXT((*font)->mCCMap, c)) { - currFont = *font; - goto FoundFont; // for speed -- avoid "if" statement - } - font++; - } - currFont = FindFont(c); - - FoundFont: - // XXX avoid this test by duplicating code -- erik - if (prevFont) { - if (currFont != prevFont) { - rawWidth += prevFont->GetWidth(&aString[start], i - start); - if (rawAscent < prevFont->mMaxAscent) - rawAscent = prevFont->mMaxAscent; - if (rawDescent < prevFont->mMaxDescent) - rawDescent = prevFont->mMaxDescent; - prevFont = currFont; - start = i; - } - } - else { - prevFont = currFont; - start = i; - } - } - - if (prevFont) { - rawWidth += prevFont->GetWidth(&aString[start], i - start); - if (rawAscent < prevFont->mMaxAscent) - rawAscent = prevFont->mMaxAscent; - if (rawDescent < prevFont->mMaxDescent) - rawDescent = prevFont->mMaxDescent; - } - - float P2T; - P2T = mDeviceContext->DevUnitsToAppUnits(); - - aDimensions.width = NSToCoordRound(rawWidth * P2T); - aDimensions.ascent = NSToCoordRound(rawAscent * P2T); - aDimensions.descent = NSToCoordRound(rawDescent * P2T); - - if (nsnull != aFontID) - *aFontID = 0; - - return NS_OK; -} - -nsresult -nsFontMetricsGTK::GetTextDimensions (const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array"); - - // If we need to back up this state represents the last place - // we could break. We can use this to avoid remeasuring text - PRInt32 prevBreakState_BreakIndex = -1; // not known - // (hasn't been computed) - nscoord prevBreakState_Width = 0; // accumulated width to this point - - // Initialize OUT parameters - GetMaxAscent(aLastWordDimensions.ascent); - GetMaxDescent(aLastWordDimensions.descent); - aLastWordDimensions.width = -1; - aNumCharsFit = 0; - - // Iterate each character in the string and determine which font to use - nscoord width = 0; - PRInt32 start = 0; - nscoord aveCharWidth; - GetAveCharWidth(aveCharWidth); - - while (start < aLength) { - // Estimate how many characters will fit. Do that by - // diving the available space by the average character - // width. Make sure the estimated number of characters is - // at least 1 - PRInt32 estimatedNumChars = 0; - - if (aveCharWidth > 0) - estimatedNumChars = (aAvailWidth - width) / aveCharWidth; - - if (estimatedNumChars < 1) - estimatedNumChars = 1; - - // Find the nearest break offset - PRInt32 estimatedBreakOffset = start + estimatedNumChars; - PRInt32 breakIndex; - nscoord numChars; - - // Find the nearest place to break that is less than or equal to - // the estimated break offset - if (aLength <= estimatedBreakOffset) { - // All the characters should fit - numChars = aLength - start; - breakIndex = aNumBreaks - 1; - } - else { - breakIndex = prevBreakState_BreakIndex; - while (((breakIndex + 1) < aNumBreaks) && - (aBreaks[breakIndex + 1] <= estimatedBreakOffset)) { - ++breakIndex; - } - - if (breakIndex == prevBreakState_BreakIndex) { - ++breakIndex; // make sure we advanced past the - // previous break index - } - - numChars = aBreaks[breakIndex] - start; - } - - // Measure the text - nscoord twWidth = 0; - if ((1 == numChars) && (aString[start] == ' ')) - GetSpaceWidth(twWidth); - else if (numChars > 0) - GetWidth(&aString[start], numChars, twWidth, aContext); - - // See if the text fits - PRBool textFits = (twWidth + width) <= aAvailWidth; - - // If the text fits then update the width and the number of - // characters that fit - if (textFits) { - aNumCharsFit += numChars; - width += twWidth; - start += numChars; - - // This is a good spot to back up to if we need to so remember - // this state - prevBreakState_BreakIndex = breakIndex; - prevBreakState_Width = width; - } - else { - // See if we can just back up to the previous saved - // state and not have to measure any text - if (prevBreakState_BreakIndex > 0) { - // If the previous break index is just before the - // current break index then we can use it - if (prevBreakState_BreakIndex == (breakIndex - 1)) { - aNumCharsFit = aBreaks[prevBreakState_BreakIndex]; - width = prevBreakState_Width; - break; - } - } - - // We can't just revert to the previous break state - if (0 == breakIndex) { - // There's no place to back up to, so even though - // the text doesn't fit return it anyway - aNumCharsFit += numChars; - width += twWidth; - break; - } - - // Repeatedly back up until we get to where the text - // fits or we're all the way back to the first word - width += twWidth; - while ((breakIndex >= 1) && (width > aAvailWidth)) { - twWidth = 0; - start = aBreaks[breakIndex - 1]; - numChars = aBreaks[breakIndex] - start; - - if ((1 == numChars) && (aString[start] == ' ')) - GetSpaceWidth(twWidth); - else if (numChars > 0) - GetWidth(&aString[start], numChars, twWidth, - aContext); - width -= twWidth; - aNumCharsFit = start; - breakIndex--; - } - break; - } - } - - aDimensions.width = width; - GetMaxAscent(aDimensions.ascent); - GetMaxDescent(aDimensions.descent); - - return NS_OK; -} - -struct BreakGetTextDimensionsData { - float mP2T; // IN - PRInt32 mAvailWidth; // IN - PRInt32* mBreaks; // IN - PRInt32 mNumBreaks; // IN - nscoord mSpaceWidth; // IN - nscoord mAveCharWidth; // IN - PRInt32 mEstimatedNumChars; // IN (running -- to handle the edge case of one word) - - PRInt32 mNumCharsFit; // IN/OUT -- accumulated number of chars that fit so far - nscoord mWidth; // IN/OUT -- accumulated width so far - - // If we need to back up, this state represents the last place - // we could break. We can use this to avoid remeasuring text - PRInt32 mPrevBreakState_BreakIndex; // IN/OUT, initialized as -1, i.e., not yet computed - nscoord mPrevBreakState_Width; // IN/OUT, initialized as 0 - - // Remember the fonts that we use so that we can deal with - // line-breaking in-between fonts later. mOffsets[0] is also used - // to initialize the current offset from where to start measuring - nsVoidArray* mFonts; // IN/OUT - nsVoidArray* mOffsets; // IN/OUT -}; - -static PRBool PR_CALLBACK -do_BreakGetTextDimensions(const nsFontSwitchGTK *aFontSwitch, - const PRUnichar* aSubstring, - PRUint32 aSubstringLength, - void* aData) -{ - nsFontGTK* fontGTK = aFontSwitch->mFontGTK; - - // Make sure the font is selected - BreakGetTextDimensionsData* data = (BreakGetTextDimensionsData*)aData; - - // Our current state relative to the _full_ string... - // This allows emulation of the previous code... - const PRUnichar* pstr = (const PRUnichar*)data->mOffsets->ElementAt(0); - PRInt32 numCharsFit = data->mNumCharsFit; - nscoord width = data->mWidth; - PRInt32 start = (PRInt32)(aSubstring - pstr); - PRInt32 end = start + aSubstringLength; - PRBool allDone = PR_FALSE; - - while (start < end) { - // Estimate how many characters will fit. Do that by dividing the - // available space by the average character width - PRInt32 estimatedNumChars = data->mEstimatedNumChars; - if (!estimatedNumChars && data->mAveCharWidth > 0) { - estimatedNumChars = (data->mAvailWidth - width) / data->mAveCharWidth; - } - // Make sure the estimated number of characters is at least 1 - if (estimatedNumChars < 1) { - estimatedNumChars = 1; - } - - // Find the nearest break offset - PRInt32 estimatedBreakOffset = start + estimatedNumChars; - PRInt32 breakIndex = -1; // not yet computed - PRBool inMiddleOfSegment = PR_FALSE; - nscoord numChars; - - // Avoid scanning the break array in the case where we think all - // the text should fit - if (end <= estimatedBreakOffset) { - // Everything should fit - numChars = end - start; - } - else { - // Find the nearest place to break that is less than or equal to - // the estimated break offset - breakIndex = data->mPrevBreakState_BreakIndex; - while (breakIndex + 1 < data->mNumBreaks && - data->mBreaks[breakIndex + 1] <= estimatedBreakOffset) { - ++breakIndex; - } - - if (breakIndex == -1) - breakIndex = 0; - - // We found a place to break that is before the estimated break - // offset. Where we break depends on whether the text crosses a - // segment boundary - if (start < data->mBreaks[breakIndex]) { - // The text crosses at least one segment boundary so measure to the - // break point just before the estimated break offset - numChars = PR_MIN(data->mBreaks[breakIndex], end) - start; - } - else { - // See whether there is another segment boundary between this one - // and the end of the text - if ((breakIndex < (data->mNumBreaks - 1)) && (data->mBreaks[breakIndex] < end)) { - ++breakIndex; - numChars = PR_MIN(data->mBreaks[breakIndex], end) - start; - } - else { - NS_ASSERTION(end != data->mBreaks[breakIndex], "don't expect to be at segment boundary"); - - // The text is all within the same segment - numChars = end - start; - - // Remember we're in the middle of a segment and not between - // two segments - inMiddleOfSegment = PR_TRUE; - } - } - } - - // Measure the text - nscoord twWidth, pxWidth; - if ((1 == numChars) && (pstr[start] == ' ')) { - twWidth = data->mSpaceWidth; - } - else { - pxWidth = fontGTK->GetWidth(&pstr[start], numChars); - twWidth = NSToCoordRound(float(pxWidth) * data->mP2T); - } - - // See if the text fits - PRBool textFits = (twWidth + width) <= data->mAvailWidth; - - // If the text fits then update the width and the number of - // characters that fit - if (textFits) { - numCharsFit += numChars; - width += twWidth; - - // If we computed the break index and we're not in the middle - // of a segment then this is a spot that we can back up to if - // we need to, so remember this state - if ((breakIndex != -1) && !inMiddleOfSegment) { - data->mPrevBreakState_BreakIndex = breakIndex; - data->mPrevBreakState_Width = width; - } - } - else { - // The text didn't fit. If we're out of room then we're all done - allDone = PR_TRUE; - - // See if we can just back up to the previous saved state and not - // have to measure any text - if (data->mPrevBreakState_BreakIndex != -1) { - PRBool canBackup; - - // If we're in the middle of a word then the break index - // must be the same if we can use it. If we're at a segment - // boundary, then if the saved state is for the previous - // break index then we can use it - if (inMiddleOfSegment) { - canBackup = data->mPrevBreakState_BreakIndex == breakIndex; - } else { - canBackup = data->mPrevBreakState_BreakIndex == (breakIndex - 1); - } - - if (canBackup) { - numCharsFit = data->mBreaks[data->mPrevBreakState_BreakIndex]; - width = data->mPrevBreakState_Width; - break; - } - } - - // We can't just revert to the previous break state. Find the break - // index just before the end of the text - end = start + numChars; - breakIndex = 0; - if (data->mBreaks[breakIndex] < end) { - while ((breakIndex + 1 < data->mNumBreaks) && (data->mBreaks[breakIndex + 1] < end)) { - ++breakIndex; - } - } - - if ((0 == breakIndex) && (end <= data->mBreaks[0])) { - // There's no place to back up to, so even though the text doesn't fit - // return it anyway - numCharsFit += numChars; - width += twWidth; - - // Edge case of one word: it could be that we just measured a fragment of the - // first word and its remainder involves other fonts, so we want to keep going - // until we at least measure the entire first word - if (numCharsFit < data->mBreaks[0]) { - allDone = PR_FALSE; - // From now on we don't care anymore what is the _real_ estimated - // number of characters that fits. Rather, we have no where to break - // and have to measure one word fully, but the real estimate is less - // than that one word. However, since the other bits of code rely on - // what is in "data->mEstimatedNumChars", we want to override - // "data->mEstimatedNumChars" and pass in what _has_ to be measured - // so that it is transparent to the other bits that depend on it. - data->mEstimatedNumChars = data->mBreaks[0] - numCharsFit; - start += numChars; - } - - break; - } - - // Repeatedly back up until we get to where the text fits or we're - // all the way back to the first word - width += twWidth; - while ((breakIndex >= 0) && (width > data->mAvailWidth)) { - start = data->mBreaks[breakIndex]; - numChars = end - start; - numCharsFit = start; - if ((1 == numChars) && (pstr[start] == ' ')) { - width -= data->mSpaceWidth; - } - else if (pstr + start >= aSubstring) { - // The entire fragment to chop is within the current font. - pxWidth = fontGTK->GetWidth(&pstr[start], numChars); - width -= NSToCoordRound(float(pxWidth) * data->mP2T); - } - else { - // The fragment that we want to chop extends back into previous fonts. - // We need to reverse into previous fonts. Fortunately, - // data->mFonts[] and data->mOffsets[] tell us which fonts are used - // and when. - end = data->mNumCharsFit; // same as aSubstring - pstr - data->mNumCharsFit = numCharsFit; // has got shorter... - PRInt32 k = data->mFonts->Count() - 1; - for ( ; k >= 0 && start < end; --k, end -= numChars) { - fontGTK = (nsFontGTK*)data->mFonts->ElementAt(k); - const PRUnichar* ps = (const PRUnichar*)data->mOffsets->ElementAt(k); - if (ps < pstr + start) - ps = pstr + start; - - numChars = pstr + end - ps; - NS_ASSERTION(numChars > 0, "empty string"); - - pxWidth = fontGTK->GetWidth(ps, numChars); - data->mWidth -= NSToCoordRound(float(pxWidth) * data->mP2T); - - // By construction, mFonts[k] is the last font, and - // mOffsets[k+1] is the last offset. - data->mFonts->RemoveElementAt(k); - data->mOffsets->RemoveElementAt(k+1); - } - - // We are done, update the data now because we won't do it later. - // The |if (data->mNumCharsFit != numCharsFit)| won't apply below - data->mFonts->AppendElement(fontGTK); - data->mOffsets->AppendElement((void*)&pstr[numCharsFit]); - break; - } - - --breakIndex; - end = start; - } - } - - start += numChars; - } - -#ifdef DEBUG_rbs - NS_ASSERTION(allDone || start == end, "internal error"); - NS_ASSERTION(allDone || data->mNumCharsFit != numCharsFit, "internal error"); -#endif /* DEBUG_rbs */ - - if (data->mNumCharsFit != numCharsFit) { - // some text was actually retained - data->mWidth = width; - data->mNumCharsFit = numCharsFit; - data->mFonts->AppendElement(fontGTK); - data->mOffsets->AppendElement((void*)&pstr[numCharsFit]); - } - - if (allDone) { - // stop now - return PR_FALSE; - } - - return PR_TRUE; // don't stop if we still need to measure more characters -} - -nsresult -nsFontMetricsGTK::GetTextDimensions (const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - - nscoord spaceWidth, aveCharWidth; - GetSpaceWidth(spaceWidth); - GetAveCharWidth(aveCharWidth); - - // Note: aBreaks[] is supplied to us so that the first word is - // located at aString[0 .. aBreaks[0]-1] and more generally, the - // k-th word is located at aString[aBreaks[k-1] - // .. aBreaks[k]-1]. Whitespace can be included and each of them - // counts as a word in its own right. - - // Upon completion of glyph resolution, characters that can be - // represented with fonts[i] are at offsets[i] .. offsets[i+1]-1 - - nsAutoVoidArray fonts, offsets; - offsets.AppendElement((void*)aString); - - float f; - f = mDeviceContext->DevUnitsToAppUnits(); - BreakGetTextDimensionsData data = { f, aAvailWidth, - aBreaks, aNumBreaks, - spaceWidth, aveCharWidth, - 0, 0, 0, -1, 0, &fonts, &offsets }; - - ResolveForwards(aString, aLength, do_BreakGetTextDimensions, - &data); - - if (aFontID) - *aFontID = 0; - - aNumCharsFit = data.mNumCharsFit; - aDimensions.width = data.mWidth; - - /////////////////// - // Post-processing for the ascent and descent: - // - // The width of the last word is included in the final width, but - // its ascent and descent are kept aside for the moment. The - // problem is that line-breaking may occur _before_ the last word, - // and we don't want its ascent and descent to interfere. We can - // re-measure the last word and substract its width - // later. However, we need a special care for the ascent and - // descent at the break-point. The idea is to keep the ascent and - // descent of the last word separate, and let layout consider them - // later when it has determined that line-breaking doesn't occur - // before the last word. - // - // Therefore, there are two things to do: - // 1. Determine the ascent and descent up to where line-breaking may occur. - // 2. Determine the ascent and descent of the remainder. For - // efficiency however, it is okay to bail out early if there is - // only one font (in this case, the height of the last word has no - // special effect on the total height). - - // aLastWordDimensions.width should be set to -1 to reply that we - // don't know the width of the last word since we measure multiple - // words - aLastWordDimensions.Clear(); - aLastWordDimensions.width = -1; - - PRInt32 count = fonts.Count(); - if (!count) - return NS_OK; - - nsFontGTK* fontGTK = (nsFontGTK*)fonts[0]; - NS_ASSERTION(fontGTK, "internal error in do_BreakGetTextDimensions"); - aDimensions.ascent = fontGTK->mMaxAscent; - aDimensions.descent = fontGTK->mMaxDescent; - - // fast path - normal case, quick return if there is only one font - if (count == 1) - return NS_OK; - - // get the last break index. - // If there is only one word, we end up with lastBreakIndex = - // 0. We don't need to worry about aLastWordDimensions in this - // case too. But if we didn't return earlier, it would mean that - // the unique word needs several fonts and we will still have to - // loop over the fonts to return the final height - PRInt32 lastBreakIndex = 0; - while (aBreaks[lastBreakIndex] < aNumCharsFit) - ++lastBreakIndex; - - const PRUnichar* lastWord = (lastBreakIndex > 0) - ? aString + aBreaks[lastBreakIndex-1] - : aString + aNumCharsFit; // let it point outside to play nice - // with the loop - - // now get the desired ascent and descent information... this is - // however a very fast loop of the order of the number of - // additional fonts - - PRInt32 currFont = 0; - const PRUnichar* pstr = aString; - const PRUnichar* last = aString + aNumCharsFit; - - while (pstr < last) { - fontGTK = (nsFontGTK*)fonts[currFont]; - PRUnichar* nextOffset = (PRUnichar*)offsets[++currFont]; - - // For consistent word-wrapping, we are going to handle the - // whitespace character with special care because a whitespace - // character can come from a font different from that of the - // previous word. If 'x', 'y', 'z', are Unicode points that - // require different fonts, we want 'xyz
' and 'xyz
' - // to have the same height because it gives a more stable - // rendering, especially when the window is resized at the - // edge of the word. - // If we don't do this, a 'tall' trailing whitespace, i.e., if - // the whitespace happens to come from a font with a bigger - // ascent and/or descent than all current fonts on the line, - // this can cause the next lines to be shifted down when the - // window is slowly resized to fit that whitespace. - if (*pstr == ' ') { - // skip pass the whitespace to ignore the height that it - // may contribute - ++pstr; - // get out if we reached the end - if (pstr == last) { - break; - } - // switch to the next font if we just passed the current font - if (pstr == nextOffset) { - fontGTK = (nsFontGTK*)fonts[currFont]; - nextOffset = (PRUnichar*)offsets[++currFont]; - } - } - - // see if the last word intersects with the current font - // (we are testing for 'nextOffset-1 >= lastWord' since the - // current font ends at nextOffset-1) - if (nextOffset > lastWord) { - if (aLastWordDimensions.ascent < fontGTK->mMaxAscent) { - aLastWordDimensions.ascent = fontGTK->mMaxAscent; - } - if (aLastWordDimensions.descent < fontGTK->mMaxDescent) { - aLastWordDimensions.descent = fontGTK->mMaxDescent; - } - } - - // see if we have not reached the last word yet - if (pstr < lastWord) { - if (aDimensions.ascent < fontGTK->mMaxAscent) { - aDimensions.ascent = fontGTK->mMaxAscent; - } - if (aDimensions.descent < fontGTK->mMaxDescent) { - aDimensions.descent = fontGTK->mMaxDescent; - } - } - - // advance to where the next font starts - pstr = nextOffset; - } - - return NS_OK; -} - -GdkFont * -nsFontMetricsGTK::GetCurrentGDKFont(void) -{ - return mCurrentFont->GetGDKFont(); -} - -nsresult -nsFontMetricsGTK::SetRightToLeftText(PRBool aIsRTL) -{ - return NS_OK; -} - -PRBool -nsFontMetricsGTK::GetRightToLeftText() -{ - return PR_FALSE; -} - -nsresult -nsFontMetricsGTK::GetClusterInfo(const PRUnichar *aText, - PRUint32 aLength, - PRUint8 *aClusterStarts) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -PRInt32 -nsFontMetricsGTK::GetPosition(const PRUnichar *aText, - PRUint32 aLength, - nsPoint aPt) -{ - return -1; -} - - -nsresult -nsFontMetricsGTK::GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -nsFontMetricsGTK::GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -PR_BEGIN_EXTERN_C -static int -CompareSizes(const void* aArg1, const void* aArg2, void *data) -{ - return (*((nsFontGTK**) aArg1))->mSize - (*((nsFontGTK**) aArg2))->mSize; -} -PR_END_EXTERN_C - -void -nsFontStretch::SortSizes(void) -{ - NS_QuickSort(mSizes, mSizesCount, sizeof(*mSizes), CompareSizes, NULL); -} - -void -nsFontWeight::FillStretchHoles(void) -{ - int i, j; - - for (i = 0; i < 9; i++) { - if (mStretches[i]) { - mStretches[i]->SortSizes(); - } - } - - if (!mStretches[4]) { - for (i = 5; i < 9; i++) { - if (mStretches[i]) { - mStretches[4] = mStretches[i]; - break; - } - } - if (!mStretches[4]) { - for (i = 3; i >= 0; i--) { - if (mStretches[i]) { - mStretches[4] = mStretches[i]; - break; - } - } - } - } - - for (i = 5; i < 9; i++) { - if (!mStretches[i]) { - for (j = i + 1; j < 9; j++) { - if (mStretches[j]) { - mStretches[i] = mStretches[j]; - break; - } - } - if (!mStretches[i]) { - for (j = i - 1; j >= 0; j--) { - if (mStretches[j]) { - mStretches[i] = mStretches[j]; - break; - } - } - } - } - } - for (i = 3; i >= 0; i--) { - if (!mStretches[i]) { - for (j = i - 1; j >= 0; j--) { - if (mStretches[j]) { - mStretches[i] = mStretches[j]; - break; - } - } - if (!mStretches[i]) { - for (j = i + 1; j < 9; j++) { - if (mStretches[j]) { - mStretches[i] = mStretches[j]; - break; - } - } - } - } - } -} - -void -nsFontStyle::FillWeightHoles(void) -{ - int i, j; - - for (i = 0; i < 9; i++) { - if (mWeights[i]) { - mWeights[i]->FillStretchHoles(); - } - } - - if (!mWeights[3]) { - for (i = 4; i < 9; i++) { - if (mWeights[i]) { - mWeights[3] = mWeights[i]; - break; - } - } - if (!mWeights[3]) { - for (i = 2; i >= 0; i--) { - if (mWeights[i]) { - mWeights[3] = mWeights[i]; - break; - } - } - } - } - - // CSS2, section 15.5.1 - if (!mWeights[4]) { - mWeights[4] = mWeights[3]; - } - for (i = 5; i < 9; i++) { - if (!mWeights[i]) { - for (j = i + 1; j < 9; j++) { - if (mWeights[j]) { - mWeights[i] = mWeights[j]; - break; - } - } - if (!mWeights[i]) { - for (j = i - 1; j >= 0; j--) { - if (mWeights[j]) { - mWeights[i] = mWeights[j]; - break; - } - } - } - } - } - for (i = 2; i >= 0; i--) { - if (!mWeights[i]) { - for (j = i - 1; j >= 0; j--) { - if (mWeights[j]) { - mWeights[i] = mWeights[j]; - break; - } - } - if (!mWeights[i]) { - for (j = i + 1; j < 9; j++) { - if (mWeights[j]) { - mWeights[i] = mWeights[j]; - break; - } - } - } - } - } -} - -void -nsFontNode::FillStyleHoles(void) -{ - if (mHolesFilled) { - return; - } - mHolesFilled = 1; - -#ifdef DEBUG_DUMP_TREE - DumpFamily(this); -#endif - - for (int i = 0; i < 3; i++) { - if (mStyles[i]) { - mStyles[i]->FillWeightHoles(); - } - } - - // XXX If both italic and oblique exist, there is probably something - // wrong. Try counting the fonts, and removing the one that has less. - if (!mStyles[NS_FONT_STYLE_NORMAL]) { - if (mStyles[NS_FONT_STYLE_ITALIC]) { - mStyles[NS_FONT_STYLE_NORMAL] = mStyles[NS_FONT_STYLE_ITALIC]; - } - else { - mStyles[NS_FONT_STYLE_NORMAL] = mStyles[NS_FONT_STYLE_OBLIQUE]; - } - } - if (!mStyles[NS_FONT_STYLE_ITALIC]) { - if (mStyles[NS_FONT_STYLE_OBLIQUE]) { - mStyles[NS_FONT_STYLE_ITALIC] = mStyles[NS_FONT_STYLE_OBLIQUE]; - } - else { - mStyles[NS_FONT_STYLE_ITALIC] = mStyles[NS_FONT_STYLE_NORMAL]; - } - } - if (!mStyles[NS_FONT_STYLE_OBLIQUE]) { - if (mStyles[NS_FONT_STYLE_ITALIC]) { - mStyles[NS_FONT_STYLE_OBLIQUE] = mStyles[NS_FONT_STYLE_ITALIC]; - } - else { - mStyles[NS_FONT_STYLE_OBLIQUE] = mStyles[NS_FONT_STYLE_NORMAL]; - } - } - -#ifdef DEBUG_DUMP_TREE - DumpFamily(this); -#endif -} - -static void -SetCharsetLangGroup(nsFontCharSetInfo* aCharSetInfo) -{ - if (!aCharSetInfo->mCharSet || aCharSetInfo->mLangGroup) - return; - - nsresult res; - - res = gCharSetManager->GetCharsetLangGroupRaw(aCharSetInfo->mCharSet, - &aCharSetInfo->mLangGroup); - if (NS_FAILED(res)) { - aCharSetInfo->mLangGroup = NS_NewAtom(""); -#ifdef NOISY_FONTS - printf("=== cannot get lang group for %s\n", aCharSetInfo->mCharSet); -#endif - } -} - -#define GET_WEIGHT_INDEX(index, weight) \ - do { \ - (index) = WEIGHT_INDEX(weight); \ - if ((index) < 0) { \ - (index) = 0; \ - } \ - else if ((index) > 8) { \ - (index) = 8; \ - } \ - } while (0) - -nsFontGTK* -nsFontMetricsGTK::SearchNode(nsFontNode* aNode, PRUint32 aChar) -{ - if (aNode->mDummy) { - return nsnull; - } - - nsFontCharSetInfo* charSetInfo = aNode->mCharSetInfo; - - /* - * mCharSet is set if we know which glyphs will be found in these fonts. - * If mCCMap has already been created for this charset, we compare it with - * the mCCMaps of the previously loaded fonts. If it is the same as any of - * the previous ones, we return nsnull because there is no point in - * loading a font with the same map. - */ - if (charSetInfo->mCharSet) { - // if not BMP char, ignore charSetInfo->mCCMap checking - // because the exact ccmap is never created before loading - // NEED TO FIX: need better way - if (!IS_IN_BMP(aChar) ) { - goto check_done; - } - PRUint16* ccmap = charSetInfo->mCCMap; - if (ccmap) { - for (int i = 0; i < mLoadedFontsCount; i++) { - if (mLoadedFonts[i]->mCCMap == ccmap) { - return nsnull; - } - } - } - else { - if (!SetUpFontCharSetInfo(charSetInfo)) - return nsnull; - } - } - else { - if ((!mIsUserDefined) && (charSetInfo == &Unknown)) { - return nsnull; - } - } - -check_done: - - aNode->FillStyleHoles(); - nsFontStyle* style = aNode->mStyles[mStyleIndex]; - - nsFontWeight** weights = style->mWeights; - int weight = mFont.weight; - int steps = (weight % 100); - int weightIndex; - if (steps) { - if (steps < 10) { - int base = (weight - steps); - GET_WEIGHT_INDEX(weightIndex, base); - while (steps--) { - nsFontWeight* prev = weights[weightIndex]; - for (weightIndex++; weightIndex < 9; weightIndex++) { - if (weights[weightIndex] != prev) { - break; - } - } - if (weightIndex >= 9) { - weightIndex = 8; - } - } - } - else if (steps > 90) { - steps = (100 - steps); - int base = (weight + steps); - GET_WEIGHT_INDEX(weightIndex, base); - while (steps--) { - nsFontWeight* prev = weights[weightIndex]; - for (weightIndex--; weightIndex >= 0; weightIndex--) { - if (weights[weightIndex] != prev) { - break; - } - } - if (weightIndex < 0) { - weightIndex = 0; - } - } - } - else { - GET_WEIGHT_INDEX(weightIndex, weight); - } - } - else { - GET_WEIGHT_INDEX(weightIndex, weight); - } - - FIND_FONT_PRINTF((" load font %s", aNode->mName.get())); - return PickASizeAndLoad(weights[weightIndex]->mStretches[mStretchIndex], - charSetInfo, aChar, aNode->mName.get()); -} - -static void -SetFontLangGroupInfo(nsFontCharSetMap* aCharSetMap) -{ - nsFontLangGroup *fontLangGroup = aCharSetMap->mFontLangGroup; - if (!fontLangGroup) - return; - - // get the atom for mFontLangGroup->mFontLangGroupName so we can - // apply fontLangGroup operations to it - // eg: search for related groups, check for scaling prefs - const char *langGroup = fontLangGroup->mFontLangGroupName; - - // the font.scale prefs don't make sense without a langGroup - // XXX FIX!!! if langGroup is "", we need to bypass the font.scale stuff - if (!langGroup) - langGroup = ""; - if (!fontLangGroup->mFontLangGroupAtom) { - fontLangGroup->mFontLangGroupAtom = NS_NewAtom(langGroup); - } - - // hack : map 'x-zh-TWHK' to 'zh-TW' when retrieving font scaling-control - // preferences via |Get*Pref|. - // XXX : This would make the font scaling controls for - // zh-HK NOT work if a font common to zh-TW and zh-HK (e.g. big5-0) - // were chosen for zh-HK. An alternative would be to make it - // locale-dependent. Even with that, it'd work only under zh-HK locale. - if (fontLangGroup->mFontLangGroupAtom == gZHTWHK) { - langGroup = "zh-TW"; - } - - // get the font scaling controls - nsFontCharSetInfo *charSetInfo = aCharSetMap->mInfo; - if (!charSetInfo->mInitedSizeInfo) { - charSetInfo->mInitedSizeInfo = PR_TRUE; - - nsCAutoString name; - nsresult rv; - name.Assign("font.scale.outline.min."); - name.Append(langGroup); - rv = gPref->GetIntPref(name.get(), &charSetInfo->mOutlineScaleMin); - if (NS_SUCCEEDED(rv)) - SIZE_FONT_PRINTF(("%s = %d", name.get(), charSetInfo->mOutlineScaleMin)); - else - charSetInfo->mOutlineScaleMin = gOutlineScaleMinimum; - - name.Assign("font.scale.aa_bitmap.min."); - name.Append(langGroup); - rv = gPref->GetIntPref(name.get(), &charSetInfo->mAABitmapScaleMin); - if (NS_SUCCEEDED(rv)) - SIZE_FONT_PRINTF(("%s = %d", name.get(), charSetInfo->mAABitmapScaleMin)); - else - charSetInfo->mAABitmapScaleMin = gAABitmapScaleMinimum; - - name.Assign("font.scale.bitmap.min."); - name.Append(langGroup); - rv = gPref->GetIntPref(name.get(), &charSetInfo->mBitmapScaleMin); - if (NS_SUCCEEDED(rv)) - SIZE_FONT_PRINTF(("%s = %d", name.get(), charSetInfo->mBitmapScaleMin)); - else - charSetInfo->mBitmapScaleMin = gBitmapScaleMinimum; - - name.Assign("font.scale.aa_bitmap.oversize."); - name.Append(langGroup); - PRInt32 percent = 0; - rv = gPref->GetIntPref(name.get(), &percent); - if (NS_SUCCEEDED(rv)) { - charSetInfo->mAABitmapOversize = percent/100.0; - SIZE_FONT_PRINTF(("%s = %g", name.get(), charSetInfo->mAABitmapOversize)); - } - else - charSetInfo->mAABitmapOversize = gAABitmapOversize; - - percent = 0; - name.Assign("font.scale.aa_bitmap.undersize."); - name.Append(langGroup); - rv = gPref->GetIntPref(name.get(), &percent); - if (NS_SUCCEEDED(rv)) { - charSetInfo->mAABitmapUndersize = percent/100.0; - SIZE_FONT_PRINTF(("%s = %g", name.get(),charSetInfo->mAABitmapUndersize)); - } - else - charSetInfo->mAABitmapUndersize = gAABitmapUndersize; - - PRBool val = PR_TRUE; - name.Assign("font.scale.aa_bitmap.always."); - name.Append(langGroup); - rv = gPref->GetBoolPref(name.get(), &val); - if (NS_SUCCEEDED(rv)) { - charSetInfo->mAABitmapScaleAlways = val; - SIZE_FONT_PRINTF(("%s = %d", name.get(),charSetInfo->mAABitmapScaleAlways)); - } - else - charSetInfo->mAABitmapScaleAlways = gAABitmapScaleAlways; - - percent = 0; - name.Assign("font.scale.bitmap.oversize."); - name.Append(langGroup); - rv = gPref->GetIntPref(name.get(), &percent); - if (NS_SUCCEEDED(rv)) { - charSetInfo->mBitmapOversize = percent/100.0; - SIZE_FONT_PRINTF(("%s = %g", name.get(), charSetInfo->mBitmapOversize)); - } - else - charSetInfo->mBitmapOversize = gBitmapOversize; - - percent = 0; - name.Assign("font.scale.bitmap.undersize."); - name.Append(langGroup); - rv = gPref->GetIntPref(name.get(), &percent); - if (NS_SUCCEEDED(rv)) { - charSetInfo->mBitmapUndersize = percent/100.0; - SIZE_FONT_PRINTF(("%s = %g", name.get(), charSetInfo->mBitmapUndersize)); - } - else - charSetInfo->mBitmapUndersize = gBitmapUndersize; - } -} - -static nsFontStyle* -NodeGetStyle(nsFontNode* aNode, int aStyleIndex) -{ - nsFontStyle* style = aNode->mStyles[aStyleIndex]; - if (!style) { - style = new nsFontStyle; - if (!style) { - return nsnull; - } - aNode->mStyles[aStyleIndex] = style; - } - return style; -} - -static nsFontWeight* -NodeGetWeight(nsFontStyle* aStyle, int aWeightIndex) -{ - nsFontWeight* weight = aStyle->mWeights[aWeightIndex]; - if (!weight) { - weight = new nsFontWeight; - if (!weight) { - return nsnull; - } - aStyle->mWeights[aWeightIndex] = weight; - } - return weight; -} - -static nsFontStretch* -NodeGetStretch(nsFontWeight* aWeight, int aStretchIndex) -{ - nsFontStretch* stretch = aWeight->mStretches[aStretchIndex]; - if (!stretch) { - stretch = new nsFontStretch; - if (!stretch) { - return nsnull; - } - aWeight->mStretches[aStretchIndex] = stretch; - } - return stretch; -} - -static PRBool -NodeAddScalable(nsFontStretch* aStretch, PRBool aOutlineScaled, - const char *aDashFoundry, const char *aFamily, - const char *aWeight, const char * aSlant, - const char *aWidth, const char *aStyle, - const char *aSpacing, const char *aCharSet) -{ - // if we have both an outline scaled font and a bitmap - // scaled font pick the outline scaled font - if ((aStretch->mScalable) && (!aStretch->mOutlineScaled) - && (aOutlineScaled)) { - PR_smprintf_free(aStretch->mScalable); - aStretch->mScalable = nsnull; - } - if (!aStretch->mScalable) { - aStretch->mOutlineScaled = aOutlineScaled; - if (aOutlineScaled) { - aStretch->mScalable = - PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-0-0-%s-*-%s", - aDashFoundry, aFamily, aWeight, aSlant, aWidth, aStyle, - aSpacing, aCharSet); - if (!aStretch->mScalable) - return PR_FALSE; - } - else { - aStretch->mScalable = - PR_smprintf("%s-%s-%s-%s-%s-%s-%%d-*-*-*-%s-*-%s", - aDashFoundry, aFamily, aWeight, aSlant, aWidth, aStyle, - aSpacing, aCharSet); - if (!aStretch->mScalable) - return PR_FALSE; - } - } - return PR_TRUE; -} - -static PRBool -NodeAddSize(nsFontStretch* aStretch, - int aPixelSize, int aPointSize, - float scaler, - int aResX, int aResY, - const char *aDashFoundry, const char *aFamily, - const char *aWeight, const char * aSlant, - const char *aWidth, const char *aStyle, - const char *aSpacing, const char *aCharSet, - nsFontCharSetInfo* aCharSetInfo) -{ - if (scaler!=1.0f) - { - aPixelSize = int(float(aPixelSize) * scaler); - aPointSize = int(float(aPointSize) * scaler); - aResX = 0; - aResY = 0; - } - - PRBool haveSize = PR_FALSE; - if (aStretch->mSizesCount) { - nsFontGTK** end = &aStretch->mSizes[aStretch->mSizesCount]; - nsFontGTK** s; - for (s = aStretch->mSizes; s < end; s++) { - if ((*s)->mSize == aPixelSize) { - haveSize = PR_TRUE; - break; - } - } - } - if (!haveSize) { - if (aStretch->mSizesCount == aStretch->mSizesAlloc) { - int newSize = 2 * (aStretch->mSizesAlloc ? aStretch->mSizesAlloc : 1); - nsFontGTK** newSizes = new nsFontGTK*[newSize]; - if (!newSizes) - return PR_FALSE; - for (int j = aStretch->mSizesAlloc - 1; j >= 0; j--) { - newSizes[j] = aStretch->mSizes[j]; - } - aStretch->mSizesAlloc = newSize; - delete [] aStretch->mSizes; - aStretch->mSizes = newSizes; - } - char *name = PR_smprintf("%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-*-%s", - aDashFoundry, aFamily, aWeight, aSlant, aWidth, aStyle, - aPixelSize, aPointSize, aResX, aResY, aSpacing, aCharSet); - - if (!name) { - return PR_FALSE; - } - nsFontGTK* size = new nsFontGTKNormal(); - if (!size) { - return PR_FALSE; - } - aStretch->mSizes[aStretch->mSizesCount++] = size; - size->mName = name; - // size->mFont is initialized in the constructor - size->mSize = aPixelSize; - size->mBaselineAdjust = 0; - size->mCCMap = nsnull; - size->mCharSetInfo = aCharSetInfo; - } - return PR_TRUE; -} - -static void -GetFontNames(const char* aPattern, PRBool aAnyFoundry, PRBool aOnlyOutlineScaledFonts, nsFontNodeArray* aNodes) -{ -#ifdef NS_FONT_DEBUG_CALL_TRACE - if (gFontDebug & NS_FONT_DEBUG_CALL_TRACE) { - printf("GetFontNames %s\n", aPattern); - } -#endif - -#ifdef MOZ_ENABLE_FREETYPE2 - // get FreeType fonts - nsFT2FontNode::GetFontNames(aPattern, aNodes); -#endif - - nsCAutoString previousNodeName; - nsHashtable* node_hash; - if (aAnyFoundry) { - NS_ASSERTION(aPattern[1] == '*', "invalid 'anyFoundry' pattern"); - node_hash = gAFRENodes; - } - else { - node_hash = gFFRENodes; - } - -#ifdef ENABLE_X_FONT_BANNING - int screen_xres, - screen_yres; - /* Get Xserver DPI. - * We cannot use Mozilla's API here because it may "override" the DPI - * got from the Xserver via prefs. But we want to filter ("ban") fonts - * we get from the Xserver which _it_(=Xserver) has "choosen" for us - * using its DPI value ... - */ - screen_xres = int((float(::gdk_screen_width()) / (float(::gdk_screen_width_mm()) / 25.4f)) + 0.5f); - screen_yres = int((float(::gdk_screen_height()) / (float(::gdk_screen_height_mm()) / 25.4f)) + 0.5f); -#endif /* ENABLE_X_FONT_BANNING */ - - BANNED_FONT_PRINTF(("Loading font '%s'", aPattern)); - /* - * We do not use XListFontsWithInfo here, because it is very expensive. - * Instead, we get that info at the time when we actually load the font. - */ - int count; - char** list = ::XListFonts(GDK_DISPLAY(), aPattern, INT_MAX, &count); - if ((!list) || (count < 1)) { - return; - } - for (int i = 0; i < count; i++) { - char name[256]; /* X11 font names are never larger than 255 chars */ - strcpy(name, list[i]); - - /* Check if we can handle the font name ('*' and '?' are only valid in - * input patterns passed as argument to |XListFont()|&co. but _not_ in - * font names returned by these functions (see bug 136743 ("xlib complains - * a lot about fonts with '*' in the XLFD string"))) */ - if ((!name) || (name[0] != '-') || (PL_strpbrk(name, "*?") != nsnull)) { - continue; - } - - char buf[512]; - PL_strncpyz(buf, name, sizeof(buf)); - char *fName = buf; - char* p = name + 1; - int scalable = 0; - PRBool outline_scaled = PR_FALSE; - int resX = -1, - resY = -1; - -#ifdef FIND_FIELD -#undef FIND_FIELD -#endif -#define FIND_FIELD(var) \ - char* var = p; \ - while ((*p) && ((*p) != '-')) { \ - p++; \ - } \ - if (*p) { \ - *p++ = 0; \ - } \ - else { \ - continue; \ - } - -#ifdef SKIP_FIELD -#undef SKIP_FIELD -#endif -#define SKIP_FIELD(var) \ - while ((*p) && ((*p) != '-')) { \ - p++; \ - } \ - if (*p) { \ - p++; \ - } \ - else { \ - continue; \ - } - - FIND_FIELD(foundry); - // XXX What to do about the many Applix fonts that start with "ax"? - FIND_FIELD(familyName); - FIND_FIELD(weightName); - FIND_FIELD(slant); - FIND_FIELD(setWidth); - FIND_FIELD(addStyle); - FIND_FIELD(pixelSize); - if (pixelSize[0] == '0') { - scalable = 1; - } - FIND_FIELD(pointSize); - if (pointSize[0] == '0') { - scalable = 1; - } - FIND_FIELD(resolutionX); - resX = atoi(resolutionX); - NS_ASSERTION(!(resolutionX[0] != '0' && resX == 0), "atoi(resolutionX) failure."); - if (resolutionX[0] == '0') { - scalable = 1; - } - FIND_FIELD(resolutionY); - resY = atoi(resolutionY); - NS_ASSERTION(!(resolutionY[0] != '0' && resY == 0), "atoi(resolutionY) failure."); - if (resolutionY[0] == '0') { - scalable = 1; - } - // check if bitmap non-scaled font - if ((pixelSize[0] != '0') || (pointSize[0] != '0')) { - SCALED_FONT_PRINTF(("bitmap (non-scaled) font: %s", fName)); - } - // check if bitmap scaled font - else if ((pixelSize[0] == '0') && (pointSize[0] == '0') - && (resolutionX[0] != '0') && (resolutionY[0] != '0')) { - SCALED_FONT_PRINTF(("bitmap scaled font: %s", fName)); - } - // check if outline scaled font - else if ((pixelSize[0] == '0') && (pointSize[0] == '0') - && (resolutionX[0] == '0') && (resolutionY[0] == '0')) { - outline_scaled = PR_TRUE; - SCALED_FONT_PRINTF(("outline scaled font: %s", fName)); - } - else { - SCALED_FONT_PRINTF(("unexpected font values: %s", fName)); - SCALED_FONT_PRINTF((" pixelSize[0] = %c", pixelSize[0])); - SCALED_FONT_PRINTF((" pointSize[0] = %c", pointSize[0])); - SCALED_FONT_PRINTF((" resolutionX[0] = %c", resolutionX[0])); - SCALED_FONT_PRINTF((" resolutionY[0] = %c", resolutionY[0])); - static PRBool already_complained = PR_FALSE; - // only complaing once - if (!already_complained) { - already_complained = PR_TRUE; - NS_ASSERTION(pixelSize[0] == '0', "font scaler type test failed"); - NS_ASSERTION(pointSize[0] == '0', "font scaler type test failed"); - NS_ASSERTION(resolutionX[0] == '0', "font scaler type test failed"); - NS_ASSERTION(resolutionY[0] == '0', "font scaler type test failed"); - } - } - FIND_FIELD(spacing); - FIND_FIELD(averageWidth); - if (averageWidth[0] == '0') { - scalable = 1; -/* Workaround for bug 103159 ("sorting fonts by foundry names cause font - * size of css ignored in some cases"). - * Hardcoded font ban until bug 104075 ("need X font banning") has been - * implemented. See http://bugzilla.mozilla.org/show_bug.cgi?id=94327#c34 - * for additional comments... - */ -#ifndef DISABLE_WORKAROUND_FOR_BUG_103159 - // skip 'mysterious' and 'spurious' cases like - // -adobe-times-medium-r-normal--17-120-100-100-p-0-iso8859-9 - if ((pixelSize[0] != '0' || pointSize[0] != 0) && - (outline_scaled == PR_FALSE)) { - PR_LOG(FontMetricsGTKLM, PR_LOG_DEBUG, ("rejecting font '%s' (via hardcoded workaround for bug 103159)\n", list[i])); - BANNED_FONT_PRINTF(("rejecting font '%s' (via hardcoded workaround for bug 103159)", list[i])); - continue; - } -#endif /* DISABLE_WORKAROUND_FOR_BUG_103159 */ - } - char* charSetName = p; // CHARSET_REGISTRY & CHARSET_ENCODING - if (!*charSetName) { - continue; - } - - if (aOnlyOutlineScaledFonts && (outline_scaled == PR_FALSE)) { - continue; - } - -#ifdef ENABLE_X_FONT_BANNING -#define BOOL2STR(b) ((b)?("true"):("false")) - if (gFontRejectRegEx || gFontAcceptRegEx) { - char fmatchbuf[512]; /* See sprintf() below. */ - - sprintf(fmatchbuf, "fname=%s;scalable=%s;outline_scaled=%s;xdisplay=%s;xdpy=%d;ydpy=%d;xdevice=%s", - list[i], /* full font name */ - BOOL2STR(scalable), - BOOL2STR(outline_scaled), - XDisplayString(GDK_DISPLAY()), - screen_xres, - screen_yres, - "display" /* Xlib gfx supports other devices like "printer", too - DO NOT REMOVE! */ - ); -#undef BOOL2STR - - if (gFontRejectRegEx) { - /* reject font if reject pattern matches it... */ - if (regexec(gFontRejectRegEx, fmatchbuf, 0, nsnull, 0) == REG_OK) { - PR_LOG(FontMetricsGTKLM, PR_LOG_DEBUG, ("rejecting font '%s' (via reject pattern)\n", fmatchbuf)); - BANNED_FONT_PRINTF(("rejecting font '%s' (via reject pattern)", fmatchbuf)); - continue; - } - } - - if (gFontAcceptRegEx) { - if (regexec(gFontAcceptRegEx, fmatchbuf, 0, nsnull, 0) == REG_NOMATCH) { - PR_LOG(FontMetricsGTKLM, PR_LOG_DEBUG, ("rejecting font '%s' (via accept pattern)\n", fmatchbuf)); - BANNED_FONT_PRINTF(("rejecting font '%s' (via accept pattern)", fmatchbuf)); - continue; - } - } - } -#endif /* ENABLE_X_FONT_BANNING */ - - nsFontCharSetMap *charSetMap = GetCharSetMap(charSetName); - nsFontCharSetInfo* charSetInfo = charSetMap->mInfo; - // indirection for font specific charset encoding - if (charSetInfo == &Special) { - nsCAutoString familyCharSetName(familyName); - familyCharSetName.Append('-'); - familyCharSetName.Append(charSetName); - nsCStringKey familyCharSetKey(familyCharSetName); - charSetMap = NS_STATIC_CAST(nsFontCharSetMap*, gSpecialCharSets->Get(&familyCharSetKey)); - if (!charSetMap) - charSetMap = gNoneCharSetMap; - charSetInfo = charSetMap->mInfo; - } - if (!charSetInfo) { -#ifdef NOISY_FONTS - printf("cannot find charset %s\n", charSetName); -#endif - charSetInfo = &Unknown; - } - SetCharsetLangGroup(charSetInfo); - SetFontLangGroupInfo(charSetMap); - - nsCAutoString nodeName; - if (aAnyFoundry) - nodeName.Assign('*'); - else - nodeName.Assign(foundry); - nodeName.Append('-'); - nodeName.Append(familyName); - nodeName.Append('-'); - nodeName.Append(charSetName); - nsCStringKey key(nodeName); - nsFontNode* node = (nsFontNode*) node_hash->Get(&key); - if (!node) { - node = new nsFontNode; - if (!node) { - continue; - } - node_hash->Put(&key, node); - node->mName = nodeName; - node->mCharSetInfo = charSetInfo; - } - - int found = 0; - if (nodeName == previousNodeName) { - found = 1; - } - else { - found = (aNodes->IndexOf(node) >= 0); - } - previousNodeName = nodeName; - if (!found) { - aNodes->AppendElement(node); - } - - int styleIndex; - // XXX This does not cover the full XLFD spec for SLANT. - switch (slant[0]) { - case 'i': - styleIndex = NS_FONT_STYLE_ITALIC; - break; - case 'o': - styleIndex = NS_FONT_STYLE_OBLIQUE; - break; - case 'r': - default: - styleIndex = NS_FONT_STYLE_NORMAL; - break; - } - nsFontStyle* style = NodeGetStyle(node, styleIndex); - if (!style) - continue; - - nsCStringKey weightKey(weightName); - int weightNumber = NS_PTR_TO_INT32(gWeights->Get(&weightKey)); - if (!weightNumber) { -#ifdef NOISY_FONTS - printf("cannot find weight %s\n", weightName); -#endif - weightNumber = NS_FONT_WEIGHT_NORMAL; - } - int weightIndex = WEIGHT_INDEX(weightNumber); - nsFontWeight* weight = NodeGetWeight(style, weightIndex); - if (!weight) - continue; - - nsCStringKey setWidthKey(setWidth); - int stretchIndex = NS_PTR_TO_INT32(gStretches->Get(&setWidthKey)); - if (!stretchIndex) { -#ifdef NOISY_FONTS - printf("cannot find stretch %s\n", setWidth); -#endif - stretchIndex = 5; - } - stretchIndex--; - nsFontStretch* stretch = NodeGetStretch(weight, stretchIndex); - if (!stretch) - continue; - - if (scalable) { - if (!NodeAddScalable(stretch, outline_scaled, name, familyName, - weightName, slant, setWidth, addStyle, spacing, charSetName)) - continue; - } - - // get pixel size before the string is changed - int pixels, - points; - - pixels = atoi(pixelSize); - points = atoi(pointSize); - - if (pixels) { - if (gScaleBitmapFontsWithDevScale && (gDevScale > 1.0f)) { - /* Add a font size which is exactly scaled as the scaling factor ... */ - if (!NodeAddSize(stretch, pixels, points, gDevScale, resX, resY, name, familyName, weightName, - slant, setWidth, addStyle, spacing, charSetName, charSetInfo)) - continue; - - /* ... and offer a range of scaled fonts with integer scaling factors - * (we're taking half steps between integers, too - to avoid too big - * steps between font sizes) */ - float minScaler = PR_MAX(gDevScale / 2.0f, 1.5f), - maxScaler = gDevScale * 2.f, - scaler; - for( scaler = minScaler ; scaler <= maxScaler ; scaler += 0.5f ) - { - if (!NodeAddSize(stretch, pixels, points, scaler, resX, resY, name, familyName, weightName, - slant, setWidth, addStyle, spacing, charSetName, charSetInfo)) - break; - } - if (scaler <= maxScaler) { - continue; /* |NodeAddSize| returned an error in the loop above... */ - } - } - else - { - if (!NodeAddSize(stretch, pixels, points, 1.0f, resX, resY, name, familyName, weightName, - slant, setWidth, addStyle, spacing, charSetName, charSetInfo)) - continue; - } - } - } - XFreeFontNames(list); - -#ifdef DEBUG_DUMP_TREE - DumpTree(); -#endif -} - -static nsresult -GetAllFontNames(void) -{ - if (!gGlobalList) { - // This may well expand further (families * sizes * styles?), but it's - // only created once. - gGlobalList = new nsFontNodeArray; - if (!gGlobalList) { - return NS_ERROR_OUT_OF_MEMORY; - } - /* Using "-*" instead of the full-qualified "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" - * because it's faster and "smarter" - see bug 34242 for details. */ - GetFontNames("-*", PR_FALSE, PR_FALSE, gGlobalList); - } - - return NS_OK; -} - -static nsFontFamily* -FindFamily(nsCString* aName) -{ - nsCStringKey key(*aName); - nsFontFamily* family = (nsFontFamily*) gFamilies->Get(&key); - if (!family) { - family = new nsFontFamily(); - if (family) { - char pattern[256]; - PR_snprintf(pattern, sizeof(pattern), "-*-%s-*-*-*-*-*-*-*-*-*-*-*-*", - aName->get()); - GetFontNames(pattern, PR_TRUE, gForceOutlineScaledFonts, &family->mNodes); - gFamilies->Put(&key, family); - } - } - - return family; -} - -nsresult -nsFontMetricsGTK::FamilyExists(nsIDeviceContext *aDevice, const nsString& aName) -{ - if (!gInitialized) { - nsresult res = InitGlobals(aDevice); - if (NS_FAILED(res)) - return res; - } - - if (!IsASCIIFontName(aName)) { - return NS_ERROR_FAILURE; - } - - nsCAutoString name; - name.AssignWithConversion(aName.get()); - ToLowerCase(name); - nsFontFamily* family = FindFamily(&name); - if (family && family->mNodes.Count()) { - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - -PRUint32 -nsFontMetricsGTK::GetHints(void) -{ - PRUint32 result = 0; - - /* We can't enable fast text measuring (yet) on platforms which - * force natural alignment of datatypes (see - * http://bugzilla.mozilla.org/show_bug.cgi?id=36146#c46) ... ;-( - */ - -#ifndef CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT -#if defined(__i386) -#define CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT 1 -#endif /* __i386 */ -#endif /* !CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT */ - - static PRBool enable_fast_measure; - static PRBool getenv_done = PR_FALSE; - - /* Check for the env vars "MOZILLA_GFX_ENABLE_FAST_MEASURE" and - * "MOZILLA_GFX_DISABLE_FAST_MEASURE" to enable/disable fast text - * measuring (for debugging the feature and doing regression tests). - * This code will be removed one all issues around this new feature - * have been fixed. */ - if (!getenv_done) { -#ifdef CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT - enable_fast_measure = PR_TRUE; -#else - enable_fast_measure = PR_FALSE; -#endif /* CPU_DOES_NOT_REQUIRE_NATURAL_ALIGNMENT */ - - if (PR_GetEnv("MOZILLA_GFX_ENABLE_FAST_MEASURE")) - enable_fast_measure = PR_TRUE; - - if (PR_GetEnv("MOZILLA_GFX_DISABLE_FAST_MEASURE")) - enable_fast_measure = PR_FALSE; - - getenv_done = PR_TRUE; - } - - if (enable_fast_measure) { - // We have GetTextDimensions() - result |= NS_RENDERING_HINT_FAST_MEASURE; - } - - return result; -} - -// -// convert a FFRE (Foundry-Family-Registry-Encoding) To XLFD Pattern -// -static void -FFREToXLFDPattern(nsACString &aFFREName, nsACString &oPattern) -{ - PRInt32 charsetHyphen; - - oPattern.Append("-"); - oPattern.Append(aFFREName); - /* Search for the 3rd appearance of '-' */ - charsetHyphen = oPattern.FindChar('-'); - charsetHyphen = oPattern.FindChar('-', charsetHyphen + 1); - charsetHyphen = oPattern.FindChar('-', charsetHyphen + 1); - oPattern.Insert("-*-*-*-*-*-*-*-*-*-*", charsetHyphen); -} - -// -// substitute the charset in a FFRE (Foundry-Family-Registry-Encoding) -// -static void -FFRESubstituteCharset(nsACString &aFFREName, - const char *aReplacementCharset) -{ - PRInt32 charsetHyphen = aFFREName.FindChar('-'); - charsetHyphen = aFFREName.FindChar('-', charsetHyphen + 1); - aFFREName.Truncate(charsetHyphen+1); - aFFREName.Append(aReplacementCharset); -} - -// -// substitute the encoding in a FFRE (Foundry-Family-Registry-Encoding) -// -static void -FFRESubstituteEncoding(nsACString &aFFREName, - const char *aReplacementEncoding) -{ - PRInt32 encodingHyphen; - /* Search for the 3rd apperance of '-' */ - encodingHyphen = aFFREName.FindChar('-'); - encodingHyphen = aFFREName.FindChar('-', encodingHyphen + 1); - encodingHyphen = aFFREName.FindChar('-', encodingHyphen + 1); - aFFREName.Truncate(encodingHyphen+1); - aFFREName.Append(aReplacementEncoding); -} - -nsFontGTK* -nsFontMetricsGTK::TryNodes(nsACString &aFFREName, PRUint32 aChar) -{ - const nsPromiseFlatCString& FFREName = PromiseFlatCString(aFFREName); - - FIND_FONT_PRINTF((" TryNodes aFFREName = %s", FFREName.get())); - nsCStringKey key(FFREName); - PRBool anyFoundry = (FFREName.First() == '*'); - nsFontNodeArray* nodes = (nsFontNodeArray*) gCachedFFRESearches->Get(&key); - if (!nodes) { - nsCAutoString pattern; - FFREToXLFDPattern(aFFREName, pattern); - nodes = new nsFontNodeArray; - if (!nodes) - return nsnull; - GetFontNames(pattern.get(), anyFoundry, gForceOutlineScaledFonts, nodes); - gCachedFFRESearches->Put(&key, nodes); - } - int i, cnt = nodes->Count(); - for (i=0; iGetElement(i); - nsFontGTK * font; - font = SearchNode(node, aChar); - if (font && font->SupportsChar(aChar)) - return font; - } - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::TryNode(nsCString* aName, PRUint32 aChar) -{ - FIND_FONT_PRINTF((" TryNode aName = %s", (*aName).get())); - // - // check the specified font (foundry-family-registry-encoding) - // - if (aName->IsEmpty()) { - return nsnull; - } - nsFontGTK* font; - - nsCStringKey key(*aName); - nsFontNode* node = (nsFontNode*) gFFRENodes->Get(&key); - if (!node) { - nsCAutoString pattern; - FFREToXLFDPattern(*aName, pattern); - nsFontNodeArray nodes; - GetFontNames(pattern.get(), PR_FALSE, gForceOutlineScaledFonts, &nodes); - // no need to call gFFRENodes->Put() since GetFontNames already did - if (nodes.Count() > 0) { - // This assertion is not spurious; when searching for an FFRE - // like -*-courier-iso8859-1 TryNodes should be called not TryNode - NS_ASSERTION((nodes.Count() == 1), "unexpected number of nodes"); - node = nodes.GetElement(0); - } - else { - // add a dummy node to the hash table to avoid calling XListFonts again - node = new nsFontNode(); - if (!node) { - return nsnull; - } - gFFRENodes->Put(&key, node); - node->mDummy = 1; - } - } - - if (node) { - font = SearchNode(node, aChar); - if (font && font->SupportsChar(aChar)) - return font; - } - - // - // do not check related sub-planes for UserDefined - // - if (mIsUserDefined) { - return nsnull; - } - // - // check related sub-planes (wild-card the encoding) - // - nsCAutoString ffreName(*aName); - FFRESubstituteEncoding(ffreName, "*"); - FIND_FONT_PRINTF((" TrySubplane: wild-card the encoding")); - font = TryNodes(ffreName, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::TryLangGroup(nsIAtom* aLangGroup, nsCString* aName, PRUint32 aChar) -{ - // - // for this family check related registry-encoding (for the language) - // - FIND_FONT_PRINTF((" TryLangGroup lang group = %s, aName = %s", - atomToName(aLangGroup), (*aName).get())); - if (aName->IsEmpty()) { - return nsnull; - } - nsFontGTK* font = FindLangGroupFont(aLangGroup, aChar, aName); - return font; -} - -nsFontGTK* -nsFontMetricsGTK::TryFamily(nsCString* aName, PRUint32 aChar) -{ - // - // check the patterh "*-familyname-registry-encoding" for language - // - nsFontFamily* family = FindFamily(aName); - if (family) { - // try family name of language group first - nsCAutoString FFREName("*-"); - FFREName.Append(*aName); - FFREName.Append("-*-*"); - FIND_FONT_PRINTF((" TryFamily %s with lang group = %s", (*aName).get(), - atomToName(mLangGroup))); - nsFontGTK* font = TryLangGroup(mLangGroup, &FFREName, aChar); - if(font) { - return font; - } - - // then try family name regardless of language group - nsFontNodeArray* nodes = &family->mNodes; - PRInt32 n = nodes->Count(); - for (PRInt32 i = 0; i < n; i++) { - FIND_FONT_PRINTF((" TryFamily %s", nodes->GetElement(i)->mName.get())); - nsFontGTK* font = SearchNode(nodes->GetElement(i), aChar); - if (font && font->SupportsChar(aChar)) { - return font; - } - } - } - - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::TryAliases(nsCString* aAlias, PRUint32 aChar) -{ - nsCStringKey key(*aAlias); - char* name = (char*) gAliases->Get(&key); - if (name) { - nsCAutoString str(name); - return TryFamily(&str, aChar); - } - - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::FindUserDefinedFont(PRUint32 aChar) -{ - if (mIsUserDefined) { - FIND_FONT_PRINTF((" FindUserDefinedFont")); - nsFontGTK* font = TryNode(&mUserDefined, aChar); - mIsUserDefined = PR_FALSE; - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - } - - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::FindStyleSheetSpecificFont(PRUint32 aChar) -{ - FIND_FONT_PRINTF((" FindStyleSheetSpecificFont")); - while (mFontsIndex < mFonts.Count()) { - if (mFontIsGeneric[mFontsIndex]) { - return nsnull; - } - nsCString* familyName = mFonts.CStringAt(mFontsIndex); - - /* - * count hyphens - * XXX It might be good to try to pre-cache this information instead - * XXX of recalculating it on every font access! - */ - const char* str = familyName->get(); - FIND_FONT_PRINTF((" familyName = %s", str)); - PRUint32 len = familyName->Length(); - int hyphens = 0; - for (PRUint32 i = 0; i < len; i++) { - if (str[i] == '-') { - hyphens++; - } - } - - /* - * if there are 3 hyphens, the name is in FFRE form - * (foundry-family-registry-encoding) - * ie: something like this: - * - * adobe-times-iso8859-1 - * - * otherwise it is something like - * - * times new roman - */ - nsFontGTK* font; - if (hyphens == 3) { - font = TryNode(familyName, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - } - else { - font = TryFamily(familyName, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - font = TryAliases(familyName, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - } - // bug 42917: increment only after all of the above fails - mFontsIndex++; - } - - return nsnull; -} - -static void -PrefEnumCallback(const char* aName, void* aClosure) -{ - nsFontSearch* s = (nsFontSearch*) aClosure; - if (s->mFont) { - NS_ASSERTION(s->mFont->SupportsChar(s->mChar), "font supposed to support this char"); - return; - } - nsXPIDLCString value; - gPref->CopyCharPref(aName, getter_Copies(value)); - nsCAutoString name; - if (value.get()) { - name = value; - FIND_FONT_PRINTF((" PrefEnumCallback")); - s->mFont = s->mMetrics->TryNode(&name, s->mChar); - if (s->mFont) { - NS_ASSERTION(s->mFont->SupportsChar(s->mChar), "font supposed to support this char"); - return; - } - s->mFont = s->mMetrics->TryLangGroup(s->mMetrics->mLangGroup, &name, s->mChar); - if (s->mFont) { - NS_ASSERTION(s->mFont->SupportsChar(s->mChar), "font supposed to support this char"); - return; - } - } - gPref->CopyDefaultCharPref(aName, getter_Copies(value)); - if (value.get() && (!name.Equals(value))) { - name = value; - FIND_FONT_PRINTF((" PrefEnumCallback:default")); - s->mFont = s->mMetrics->TryNode(&name, s->mChar); - if (s->mFont) { - NS_ASSERTION(s->mFont->SupportsChar(s->mChar), "font supposed to support this char"); - return; - } - s->mFont = s->mMetrics->TryLangGroup(s->mMetrics->mLangGroup, &name, s->mChar); - NS_ASSERTION(s->mFont ? s->mFont->SupportsChar(s->mChar) : 1, "font supposed to support this char"); - } -} - -nsFontGTK* -nsFontMetricsGTK::FindStyleSheetGenericFont(PRUint32 aChar) -{ - FIND_FONT_PRINTF((" FindStyleSheetGenericFont")); - nsFontGTK* font; - - if (mTriedAllGenerics) { - return nsnull; - } - - // - // find font based on document's lang group - // - font = FindLangGroupPrefFont(mLangGroup, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - - // - // Asian smart quote glyphs are much too large for western - // documents so if this is a single byte document add a - // special "font" to tranliterate those chars rather than - // possibly find them in double byte fonts - // - // (risk management: since we are close to a ship point we have a - // control (gAllowDoubleByteSpecialChars) to disable this new feature) - // -if (gAllowDoubleByteSpecialChars) { - if (!mDocConverterType) { - if (mLoadedFontsCount) { - FIND_FONT_PRINTF(("just use the 1st converter type")); - nsFontGTK* first_font = mLoadedFonts[0]; - if (first_font->mCharSetInfo) { - mDocConverterType = first_font->mCharSetInfo->Convert; - if (mDocConverterType == SingleByteConvert ) { - FIND_FONT_PRINTF(("single byte converter for %s", atomToName(mLangGroup))); - } - else { - FIND_FONT_PRINTF(("double byte converter for %s", atomToName(mLangGroup))); - } - } - } - if (!mDocConverterType) { - mDocConverterType = SingleByteConvert; - } - if (mDocConverterType == SingleByteConvert) { - // before we put in the transliterator to disable double byte special chars - // add the x-western font before the early transliterator - // to get the EURO sign (hack) - - nsFontGTK* western_font = nsnull; - if (mLangGroup != gWesternLocale) - western_font = FindLangGroupPrefFont(gWesternLocale, aChar); - - // add the symbol font before the early transliterator - // to get the bullet (hack) - nsCAutoString symbol_ffre("*-symbol-adobe-fontspecific"); - nsFontGTK* symbol_font = TryNodes(symbol_ffre, 0x0030); - - // Add the Adobe Euro fonts before the early transliterator - nsCAutoString euro_ffre("*-euro*-adobe-fontspecific"); - nsFontGTK* euro_font = TryNodes(euro_ffre, 0x20AC); - - // add the early transliterator - // to avoid getting Japanese "special chars" such as smart - // since they are very oversized compared to western fonts - nsFontGTK* sub_font = FindSubstituteFont(aChar); - NS_ASSERTION(sub_font, "failed to get a special chars substitute font"); - if (sub_font) { - sub_font->mCCMap = gDoubleByteSpecialCharsCCMap; - AddToLoadedFontsList(sub_font); - } - if (western_font && CCMAP_HAS_CHAR_EXT(western_font->mCCMap, aChar)) { - return western_font; - } - else if (symbol_font && CCMAP_HAS_CHAR_EXT(symbol_font->mCCMap, aChar)) { - return symbol_font; - } - else if (euro_font && CCMAP_HAS_CHAR_EXT(euro_font->mCCMap, aChar)) { - return euro_font; - } - else if (sub_font && CCMAP_HAS_CHAR_EXT(sub_font->mCCMap, aChar)) { - FIND_FONT_PRINTF((" transliterate special chars for single byte docs")); - return sub_font; - } - } - } -} - - // - // find font based on user's locale's lang group - // if different from documents locale - if (gUsersLocale != mLangGroup) { - FIND_FONT_PRINTF((" find font based on user's locale's lang group")); - font = FindLangGroupPrefFont(gUsersLocale, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - } - - // - // Search all font prefs for generic - // - nsCAutoString prefix("font.name."); - prefix.Append(*mGeneric); - nsFontSearch search = { this, aChar, nsnull }; - FIND_FONT_PRINTF((" Search all font prefs for generic")); - gPref->EnumerateChildren(prefix.get(), PrefEnumCallback, &search); - if (search.mFont) { - NS_ASSERTION(search.mFont->SupportsChar(aChar), "font supposed to support this char"); - return search.mFont; - } - - // - // Search all font prefs - // - // find based on all prefs (no generic part (eg: sans-serif)) - nsCAutoString allPrefs("font.name."); - search.mFont = nsnull; - FIND_FONT_PRINTF((" Search all font prefs")); - gPref->EnumerateChildren(allPrefs.get(), PrefEnumCallback, &search); - if (search.mFont) { - NS_ASSERTION(search.mFont->SupportsChar(aChar), "font supposed to support this char"); - return search.mFont; - } - - mTriedAllGenerics = 1; - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::FindAnyFont(PRUint32 aChar) -{ - FIND_FONT_PRINTF((" FindAnyFont")); - // XXX If we get to this point, that means that we have exhausted all the - // families in the lists. Maybe we should try a list of fonts that are - // specific to the vendor of the X server here. Because XListFonts for the - // whole list is very expensive on some Unixes. - - /* - * Try all the fonts on the system. - */ - nsresult res = GetAllFontNames(); - if (NS_FAILED(res)) { - return nsnull; - } - - PRInt32 n = gGlobalList->Count(); - for (PRInt32 i = 0; i < n; i++) { - nsFontGTK* font = SearchNode(gGlobalList->GetElement(i), aChar); - if (font && font->SupportsChar(aChar)) { - // XXX We should probably write this family name out to disk, so that - // we can use it next time. I.e. prefs file or something. - return font; - } - } - - // future work: - // to properly support the substitute font we - // need to indicate here that all fonts have been tried - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::FindSubstituteFont(PRUint32 aChar) -{ - if (!mSubstituteFont) { - for (int i = 0; i < mLoadedFontsCount; i++) { - if (CCMAP_HAS_CHAR_EXT(mLoadedFonts[i]->mCCMap, 'a')) { - mSubstituteFont = new nsFontGTKSubstitute(mLoadedFonts[i]); - break; - } - } - // Currently the substitute font does not have a glyph map. - // This means that even if we have already checked all fonts - // for a particular character the mLoadedFonts will not know it. - // Thus we reparse *all* font glyph maps every time we see - // a character that ends up using a substitute font. - // future work: - // create an empty mCCMap and every time we determine a - // character will get its "glyph" from the substitute font - // mark that character in the mCCMap. - } - // mark the mCCMap to indicate that this character has a "glyph" - - // If we know that mLoadedFonts has every font's glyph map loaded - // then we can now set all the bit in the substitute font's glyph map - // and thus direct all umapped characters to the substitute - // font (without the font search). - // if tried all glyphs { - // create a substitute font with all bits set - // set all bits in mCCMap - // } - - return mSubstituteFont; -} - -// -// find font based on lang group -// - -nsFontGTK* -nsFontMetricsGTK::FindLangGroupPrefFont(nsIAtom* aLangGroup, PRUint32 aChar) -{ - nsFontGTK* font; - // - // get the font specified in prefs - // - nsCAutoString prefix("font.name."); - prefix.Append(*mGeneric); - if (aLangGroup) { - // check user set pref - nsCAutoString pref = prefix; - pref.Append(char('.')); - const char* langGroup = nsnull; - aLangGroup->GetUTF8String(&langGroup); - pref.Append(langGroup); - nsXPIDLCString value; - gPref->CopyCharPref(pref.get(), getter_Copies(value)); - nsCAutoString str; - nsCAutoString str_user; - if (value.get()) { - str = value.get(); - str_user = value.get(); - FIND_FONT_PRINTF((" user pref %s = %s", pref.get(), str.get())); - font = TryNode(&str, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - font = TryLangGroup(aLangGroup, &str, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - } - // check factory set pref - gPref->CopyDefaultCharPref(pref.get(), getter_Copies(value)); - if (value.get()) { - str = value.get(); - // check if we already tried this name - if (str != str_user) { - FIND_FONT_PRINTF((" default pref %s = %s", pref.get(), str.get())); - font = TryNode(&str, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - font = TryLangGroup(aLangGroup, &str, aChar); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - } - } - } - - // - // find any style font based on lang group - // - FIND_FONT_PRINTF((" find font based on lang group")); - font = FindLangGroupFont(aLangGroup, aChar, nsnull); - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - - return nsnull; -} - -nsFontGTK* -nsFontMetricsGTK::FindLangGroupFont(nsIAtom* aLangGroup, PRUint32 aChar, nsCString *aName) -{ - nsFontGTK* font; - - FIND_FONT_PRINTF((" lang group = %s", atomToName(aLangGroup))); - - // scan gCharSetMap for encodings with matching lang groups - nsFontCharSetMap* charSetMap; - for (charSetMap=gCharSetMap; charSetMap->mName; charSetMap++) { - nsFontLangGroup* fontLangGroup = charSetMap->mFontLangGroup; - - if ((!fontLangGroup) || (!fontLangGroup->mFontLangGroupName)) { - continue; - } - - if (!charSetMap->mInfo->mLangGroup) { - SetCharsetLangGroup(charSetMap->mInfo); - } - - if (!fontLangGroup->mFontLangGroupAtom) { - SetFontLangGroupInfo(charSetMap); - } - - // if font's langGroup is different from requested langGroup, continue. - // An exception is that font's langGroup ZHTWHK is regarded as matching - // both ZHTW and ZHHK (Freetype2 and Solaris). - if ((aLangGroup != fontLangGroup->mFontLangGroupAtom) && - (aLangGroup != charSetMap->mInfo->mLangGroup) && - (fontLangGroup->mFontLangGroupAtom != gZHTWHK || - (aLangGroup != gZHHK && aLangGroup != gZHTW))) { - continue; - } - // look for a font with this charset (registry-encoding) & char - // - nsCAutoString ffreName; - if(aName) { - // if aName was specified so call TryNode() not TryNodes() - ffreName.Assign(*aName); - FFRESubstituteCharset(ffreName, charSetMap->mName); - FIND_FONT_PRINTF((" %s ffre = %s", charSetMap->mName, ffreName.get())); - if(aName->First() == '*') { - // called from TryFamily() - font = TryNodes(ffreName, aChar); - } else { - font = TryNode(&ffreName, aChar); - } - NS_ASSERTION(font ? font->SupportsChar(aChar) : 1, "font supposed to support this char"); - } else { - // no name was specified so call TryNodes() for this charset - ffreName.Assign("*-*-*-*"); - FFRESubstituteCharset(ffreName, charSetMap->mName); - FIND_FONT_PRINTF((" %s ffre = %s", charSetMap->mName, ffreName.get())); - font = TryNodes(ffreName, aChar); - NS_ASSERTION(font ? font->SupportsChar(aChar) : 1, "font supposed to support this char"); - } - if (font) { - NS_ASSERTION(font->SupportsChar(aChar), "font supposed to support this char"); - return font; - } - } - - return nsnull; -} - -/* - * First we try to load the user-defined font, if the user-defined charset - * has been selected in the menu. - * - * Next, we try the fonts listed in the font-family property (FindStyleSheetSpecificFont). - * - * Next, we try any CSS generic font encountered in the font-family list and - * all of the fonts specified by the user for the generic (FindStyleSheetGenericFont). - * - * Next, we try all of the fonts on the system (FindAnyFont). This is - * expensive on some Unixes. - * - * Finally, we try to create a substitute font that offers substitute glyphs - * for the characters (FindSubstituteFont). - */ -nsFontGTK* -nsFontMetricsGTK::FindFont(PRUint32 aChar) -{ - FIND_FONT_PRINTF(("\nFindFont(%c/0x%04x)", aChar, aChar)); - - // If this is is the 'unknown' char (ie: converter could not - // convert it) there is no sense in searching any further for - // a font. Just returning mWesternFont - if (aChar == UCS2_REPLACEMENT_CHAR) { - FIND_FONT_PRINTF((" ignore the 'UCS2_REPLACEMENT_CHAR' character, return mWesternFont")); - return mWesternFont; - } - - nsFontGTK* font = FindUserDefinedFont(aChar); - if (!font) { - font = FindStyleSheetSpecificFont(aChar); - if (!font) { - font = FindStyleSheetGenericFont(aChar); - if (!font) { - font = FindAnyFont(aChar); - if (!font) { - font = FindSubstituteFont(aChar); - } - } - } - } - -#ifdef NS_FONT_DEBUG_CALL_TRACE - if (gFontDebug & NS_FONT_DEBUG_CALL_TRACE) { - printf("FindFont(%04X)[", aChar); - for (PRInt32 i = 0; i < mFonts.Count(); i++) { - printf("%s, ", mFonts.CStringAt(i)->get()); - } - printf("]\nreturns "); - if (font) { - printf("%s\n", font->mName ? font->mName : "(substitute)"); - } - else { - printf("NULL\n"); - } - } -#endif - - return font; -} - - -// The Font Enumerator - -nsFontEnumeratorGTK::nsFontEnumeratorGTK() -{ -} - -NS_IMPL_ISUPPORTS1(nsFontEnumeratorGTK, nsIFontEnumerator) - -typedef struct EnumerateNodeInfo -{ - PRUnichar** mArray; - int mIndex; - nsIAtom* mLangGroup; -} EnumerateNodeInfo; - -static PRIntn -EnumerateNode(void* aElement, void* aData) -{ - nsFontNode* node = (nsFontNode*) aElement; - EnumerateNodeInfo* info = (EnumerateNodeInfo*) aData; - if (info->mLangGroup != gUserDefined) { - if (node->mCharSetInfo == &Unknown) { - return PR_TRUE; // continue - } - else if (info->mLangGroup != gUnicode) { - // if font's langGroup is different from requested langGroup, continue. - // An exception is that font's langGroup ZHTWHK is regarded as matching - // both ZHTW and ZHHK (Freetype2 and Solaris). - if (node->mCharSetInfo->mLangGroup != info->mLangGroup && - (node->mCharSetInfo->mLangGroup != gZHTWHK || - (info->mLangGroup != gZHHK && info->mLangGroup != gZHTW))) { - return PR_TRUE; // continue - } - } - // else { - // if (lang == add-style-field) { - // consider it part of the lang group - // } - // else if (a Unicode font reports its lang group) { - // consider it part of the lang group - // } - // else if (lang's ranges in list of ranges) { - // consider it part of the lang group - // // Note: at present we have no way to do this test but we - // // could in the future and this would be the place to enable - // // to make the font show up in the preferences dialog - // } - // } - - } - PRUnichar** array = info->mArray; - int j = info->mIndex; - PRUnichar* str = ToNewUnicode(node->mName); - if (!str) { - for (j = j - 1; j >= 0; j--) { - nsMemory::Free(array[j]); - } - info->mIndex = 0; - return PR_FALSE; // stop - } - array[j] = str; - info->mIndex++; - - return PR_TRUE; // continue -} - -PR_BEGIN_EXTERN_C -static int -CompareFontNames(const void* aArg1, const void* aArg2, void* aClosure) -{ - const PRUnichar* str1 = *((const PRUnichar**) aArg1); - const PRUnichar* str2 = *((const PRUnichar**) aArg2); - - // XXX add nsICollation stuff - - return nsCRT::strcmp(str1, str2); -} -PR_END_EXTERN_C - -static nsresult -EnumFonts(nsIAtom* aLangGroup, const char* aGeneric, PRUint32* aCount, - PRUnichar*** aResult) -{ - nsresult res = GetAllFontNames(); - if (NS_FAILED(res)) { - return res; - } - - PRUnichar** array = - (PRUnichar**) nsMemory::Alloc(gGlobalList->Count() * sizeof(PRUnichar*)); - if (!array) { - return NS_ERROR_OUT_OF_MEMORY; - } - EnumerateNodeInfo info = { array, 0, aLangGroup }; - if (!gGlobalList->EnumerateForwards(EnumerateNode, &info)) { - nsMemory::Free(array); - return NS_ERROR_OUT_OF_MEMORY; - } - - NS_QuickSort(array, info.mIndex, sizeof(PRUnichar*), CompareFontNames, - nsnull); - - *aCount = info.mIndex; - if (*aCount) { - *aResult = array; - } - else { - nsMemory::Free(array); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsFontEnumeratorGTK::EnumerateAllFonts(PRUint32* aCount, PRUnichar*** aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - NS_ENSURE_ARG_POINTER(aCount); - *aCount = 0; - - return EnumFonts(nsnull, nsnull, aCount, aResult); -} - -NS_IMETHODIMP -nsFontEnumeratorGTK::EnumerateFonts(const char* aLangGroup, - const char* aGeneric, PRUint32* aCount, PRUnichar*** aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - NS_ENSURE_ARG_POINTER(aCount); - *aCount = 0; - - // aLangGroup=null or "" means any (i.e., don't care) - // aGeneric=null or "" means any (i.e, don't care) - nsCOMPtr langGroup; - if (aLangGroup && *aLangGroup) - langGroup = do_GetAtom(aLangGroup); - const char* generic = nsnull; - if (aGeneric && *aGeneric) - generic = aGeneric; - - // XXX still need to implement aLangGroup and aGeneric - return EnumFonts(langGroup, generic, aCount, aResult); -} - -NS_IMETHODIMP -nsFontEnumeratorGTK::HaveFontFor(const char* aLangGroup, PRBool* aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = PR_FALSE; - NS_ENSURE_ARG_POINTER(aLangGroup); - - *aResult = PR_TRUE; // always return true for now. - // Finish me - ftang - return NS_OK; -} - -NS_IMETHODIMP -nsFontEnumeratorGTK::GetDefaultFont(const char *aLangGroup, - const char *aGeneric, PRUnichar **aResult) -{ - // aLangGroup=null or "" means any (i.e., don't care) - // aGeneric=null or "" means any (i.e, don't care) - - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - - return NS_OK; -} - -NS_IMETHODIMP -nsFontEnumeratorGTK::UpdateFontList(PRBool *updateFontList) -{ - *updateFontList = PR_FALSE; // always return false for now - return NS_OK; -} - -nsFontCharSetMap * -GetCharSetMap(const char *aCharSetName) -{ - nsCStringKey charSetKey(aCharSetName); - nsFontCharSetMap* charSetMap = - (nsFontCharSetMap*) gCharSetMaps->Get(&charSetKey); - if (!charSetMap) - charSetMap = gNoneCharSetMap; - return charSetMap; -} - -#ifdef MOZ_ENABLE_FREETYPE2 -void -CharSetNameToCodeRangeBits(const char *aCharset, - PRUint32 *aCodeRange1, PRUint32 *aCodeRange2) -{ - nsFontCharSetMap *charSetMap = GetCharSetMap(aCharset); - nsFontCharSetInfo* charSetInfo = charSetMap->mInfo; - - *aCodeRange1 = charSetInfo->mCodeRange1Bits; - *aCodeRange2 = charSetInfo->mCodeRange2Bits; -} -#endif diff --git a/gfx/src/gtk/nsFontMetricsGTK.h b/gfx/src/gtk/nsFontMetricsGTK.h deleted file mode 100644 index ab522cba0332..000000000000 --- a/gfx/src/gtk/nsFontMetricsGTK.h +++ /dev/null @@ -1,448 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsFontMetricsGTK_h__ -#define nsFontMetricsGTK_h__ - -#include "nsDeviceContextGTK.h" -#include "nsIFontMetrics.h" -#include "nsIFontEnumerator.h" -#include "nsFont.h" -#include "nsString.h" -#include "nsUnitConversion.h" -#include "nsIDeviceContext.h" -#include "nsCRT.h" -#include "nsCOMPtr.h" -#include "nsRenderingContextGTK.h" -#include "nsICharRepresentable.h" -#include "nsCompressedCharMap.h" -#include "nsIFontMetricsGTK.h" -#ifdef MOZ_ENABLE_FREETYPE2 -#include "nsIFontCatalogService.h" -#endif - -#include -#include - -#undef FONT_HAS_GLYPH -#define FONT_HAS_GLYPH(map, char) IS_REPRESENTABLE(map, char) -#define WEIGHT_INDEX(weight) (((weight) / 100) - 1) - -typedef struct nsFontCharSetInfo nsFontCharSetInfo; - -typedef gint (*nsFontCharSetConverter)(nsFontCharSetInfo* aSelf, - XFontStruct* aFont, const PRUnichar* aSrcBuf, PRInt32 aSrcLen, - char* aDestBuf, PRInt32 aDestLen); - -struct nsFontCharSet; -struct nsFontFamily; -struct nsFontNode; -struct nsFontStretch; -struct nsFontWeight; -class nsXFont; - -class nsFontGTKUserDefined; -class nsFontMetricsGTK; -class nsFreeTypeFace; -class nsFontGTK; - -struct nsFontStretch -{ - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - void SortSizes(void); - - nsFontGTK** mSizes; - PRUint16 mSizesAlloc; - PRUint16 mSizesCount; - - char* mScalable; - PRBool mOutlineScaled; - nsVoidArray mScaledFonts; -#ifdef MOZ_ENABLE_FREETYPE2 - nsITrueTypeFontCatalogEntry* mFreeTypeFaceID; -#endif -}; - -struct nsFontStyle -{ - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - void FillWeightHoles(void); - - nsFontWeight* mWeights[9]; -}; - -struct nsFontWeight -{ - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - void FillStretchHoles(void); - - nsFontStretch* mStretches[9]; -}; - -struct nsFontNode -{ - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - void FillStyleHoles(void); - - nsCAutoString mName; - nsFontCharSetInfo* mCharSetInfo; - nsFontStyle* mStyles[3]; - PRUint8 mHolesFilled; - PRUint8 mDummy; -}; - -class nsFontNodeArray : public nsAutoVoidArray -{ -public: - nsFontNodeArray() {}; - - nsFontNode* GetElement(PRInt32 aIndex) - { - return (nsFontNode*) ElementAt(aIndex); - }; -}; - -/* - * Font Language Groups - * - * These Font Language Groups (FLG) indicate other related - * encodings to look at when searching for glyphs - * - */ -typedef struct nsFontLangGroup { - const char *mFontLangGroupName; - nsIAtom* mFontLangGroupAtom; -} nsFontLangGroup; - -struct nsFontCharSetMap -{ - const char* mName; - nsFontLangGroup* mFontLangGroup; - nsFontCharSetInfo* mInfo; -}; - -class nsFontGTK -{ -public: - nsFontGTK(); - nsFontGTK(nsFontGTK*); - virtual ~nsFontGTK(); - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - void LoadFont(void); - PRBool IsEmptyFont(XFontStruct*); - - inline int SupportsChar(PRUint32 aChar) - { return mCCMap && CCMAP_HAS_CHAR_EXT(mCCMap, aChar); }; - - virtual GdkFont* GetGDKFont(void); - virtual nsXFont* GetXFont(void); - virtual PRBool GetXFontIs10646(void); - virtual PRBool IsFreeTypeFont(void); - virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength) = 0; - virtual gint DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength) = 0; -#ifdef MOZ_MATHML - // bounding metrics for a string - // remember returned values are not in app units - // - to emulate GetWidth () above - virtual nsresult - GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) = 0; -#endif - - PRUint16* mCCMap; - nsFontCharSetInfo* mCharSetInfo; - char* mName; - nsFontGTKUserDefined* mUserDefinedFont; - PRUint16 mSize; - PRUint16 mAABaseSize; - PRInt16 mBaselineAdjust; - - // these values are not in app units, they need to be scaled with - // nsIDeviceContext::DevUnitsToAppUnits() - PRInt16 mMaxAscent; - PRInt16 mMaxDescent; - -protected: - GdkFont* mFont; - GdkFont* mFontHolder; - nsXFont* mXFont; - PRBool mAlreadyCalledLoadFont; -}; - -struct nsFontSwitchGTK { - // Simple wrapper on top of nsFontGTK for the moment - // Could hold other attributes of the font - nsFontGTK* mFontGTK; -}; - -typedef PRBool (*PR_CALLBACK nsFontSwitchCallbackGTK) - (const nsFontSwitchGTK *aFontSwitch, - const PRUnichar *aSubstring, - PRUint32 aSubstringLength, - void *aData); - -class nsFontMetricsGTK : public nsIFontMetricsGTK -{ -public: - nsFontMetricsGTK(); - virtual ~nsFontMetricsGTK(); - - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - NS_DECL_ISUPPORTS - - NS_IMETHOD Init(const nsFont& aFont, nsIAtom* aLangGroup, - nsIDeviceContext* aContext); - NS_IMETHOD Destroy(); - - NS_IMETHOD GetXHeight(nscoord& aResult); - NS_IMETHOD GetSuperscriptOffset(nscoord& aResult); - NS_IMETHOD GetSubscriptOffset(nscoord& aResult); - NS_IMETHOD GetStrikeout(nscoord& aOffset, nscoord& aSize); - NS_IMETHOD GetUnderline(nscoord& aOffset, nscoord& aSize); - - NS_IMETHOD GetHeight(nscoord &aHeight); - NS_IMETHOD GetNormalLineHeight(nscoord &aHeight); - NS_IMETHOD GetLeading(nscoord &aLeading); - NS_IMETHOD GetEmHeight(nscoord &aHeight); - NS_IMETHOD GetEmAscent(nscoord &aAscent); - NS_IMETHOD GetEmDescent(nscoord &aDescent); - NS_IMETHOD GetMaxHeight(nscoord &aHeight); - NS_IMETHOD GetMaxAscent(nscoord &aAscent); - NS_IMETHOD GetMaxDescent(nscoord &aDescent); - NS_IMETHOD GetMaxAdvance(nscoord &aAdvance); - NS_IMETHOD GetAveCharWidth(nscoord &aAveCharWidth); - virtual PRInt32 GetMaxStringLength(); - NS_IMETHOD GetLangGroup(nsIAtom** aLangGroup); - NS_IMETHOD GetFontHandle(nsFontHandle &aHandle); - - NS_IMETHOD GetSpaceWidth(nscoord &aSpaceWidth); - NS_IMETHOD ResolveForwards(const PRUnichar* aString, PRUint32 aLength, - nsFontSwitchCallbackGTK aFunc, void* aData); - - nsFontGTK* FindFont(PRUint32 aChar); - nsFontGTK* FindUserDefinedFont(PRUint32 aChar); - nsFontGTK* FindStyleSheetSpecificFont(PRUint32 aChar); - nsFontGTK* FindStyleSheetGenericFont(PRUint32 aChar); - nsFontGTK* FindLangGroupPrefFont(nsIAtom* aLangGroup, PRUint32 aChar); - nsFontGTK* FindLangGroupFont(nsIAtom* aLangGroup, PRUint32 aChar, nsCString* aName); - nsFontGTK* FindAnyFont(PRUint32 aChar); - nsFontGTK* FindSubstituteFont(PRUint32 aChar); - - nsFontGTK* SearchNode(nsFontNode* aNode, PRUint32 aChar); - nsFontGTK* TryAliases(nsCString* aName, PRUint32 aChar); - nsFontGTK* TryFamily(nsCString* aName, PRUint32 aChar); - nsFontGTK* TryNode(nsCString* aName, PRUint32 aChar); - nsFontGTK* TryNodes(nsACString &aFFREName, PRUint32 aChar); - nsFontGTK* TryLangGroup(nsIAtom* aLangGroup, nsCString* aName, PRUint32 aChar); - - nsFontGTK* AddToLoadedFontsList(nsFontGTK* aFont); - nsFontGTK* FindNearestSize(nsFontStretch* aStretch, PRUint16 aSize); - nsFontGTK* GetAASBBaseFont(nsFontStretch* aStretch, - nsFontCharSetInfo* aCharSet); - nsFontGTK* PickASizeAndLoad(nsFontStretch* aStretch, - nsFontCharSetInfo* aCharSet, - PRUint32 aChar, - const char *aName); - - // 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); - - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - virtual nsresult GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - - virtual nsresult 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, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface); - -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - nsRenderingContextGTK *aContext); - virtual nsresult GetBoundingMetrics(const PRUnichar *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - PRInt32 *aFontID, - nsRenderingContextGTK *aContext); -#endif /* MOZ_MATHML */ - - virtual GdkFont* GetCurrentGDKFont(void); - - virtual nsresult SetRightToLeftText(PRBool aIsRTL); - virtual PRBool GetRightToLeftText(); - - virtual nsresult GetClusterInfo(const PRUnichar *aText, - PRUint32 aLength, - PRUint8 *aClusterStarts); - - virtual PRInt32 GetPosition(const PRUnichar *aText, - PRUint32 aLength, - nsPoint aPt); - - virtual nsresult GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - - virtual nsresult GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - - static nsresult FamilyExists(nsIDeviceContext *aDevice, const nsString& aName); - static PRUint32 GetHints(void); - - //friend struct nsFontGTK; - - nsFontGTK **mLoadedFonts; - PRUint16 mLoadedFontsAlloc; - PRUint16 mLoadedFontsCount; - - nsFontGTK *mSubstituteFont; - - nsCStringArray mFonts; - PRInt32 mFontsIndex; - nsAutoVoidArray mFontIsGeneric; - - nsCAutoString mDefaultFont; - nsCString *mGeneric; - nsCOMPtr mLangGroup; - nsCAutoString mUserDefined; - - PRUint8 mTriedAllGenerics; - PRUint8 mIsUserDefined; - -protected: - void RealizeFont(); - nsFontGTK* LocateFont(PRUint32 aChar, PRInt32 & aCount); - - nsIDeviceContext *mDeviceContext; - nsFontGTK *mWesternFont; - nsFontGTK *mCurrentFont; - - nscoord mLeading; - nscoord mEmHeight; - nscoord mEmAscent; - nscoord mEmDescent; - nscoord mMaxHeight; - nscoord mMaxAscent; - nscoord mMaxDescent; - nscoord mMaxAdvance; - nscoord mXHeight; - nscoord mSuperscriptOffset; - nscoord mSubscriptOffset; - nscoord mStrikeoutSize; - nscoord mStrikeoutOffset; - nscoord mUnderlineSize; - nscoord mUnderlineOffset; - nscoord mSpaceWidth; - nscoord mAveCharWidth; - PRInt32 mMaxStringLength; - - PRUint16 mPixelSize; - PRUint8 mStretchIndex; - PRUint8 mStyleIndex; - nsFontCharSetConverter mDocConverterType; -}; - -class nsFontEnumeratorGTK : public nsIFontEnumerator -{ -public: - nsFontEnumeratorGTK(); - NS_DECL_ISUPPORTS - NS_DECL_NSIFONTENUMERATOR -}; - -class nsHashKey; -PRBool FreeNode(nsHashKey* aKey, void* aData, void* aClosure); -nsFontCharSetInfo *GetCharSetInfo(const char *aCharSetName); -#ifdef MOZ_ENABLE_FREETYPE2 -void CharSetNameToCodeRangeBits(const char*, PRUint32*, PRUint32*); -#endif -nsFontCharSetMap *GetCharSetMap(const char *aCharSetName); - - - - -#endif diff --git a/gfx/src/gtk/nsFontMetricsPango.cpp b/gfx/src/gtk/nsFontMetricsPango.cpp deleted file mode 100644 index fdaefcf84c75..000000000000 --- a/gfx/src/gtk/nsFontMetricsPango.cpp +++ /dev/null @@ -1,1838 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Christopher Blizzard - * . Portions created by the Initial Developer - * are Copyright (C) 2004 the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include "nsFont.h" -#include "nsIDeviceContext.h" -#include "nsICharsetConverterManager.h" -#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 -#include -#include -#include - -#include "mozilla-decoder.h" - -#define FORCE_PR_LOG -#include "prlog.h" - -// Globals - -static PRLogModuleInfo *gPangoFontLog; -static int gNumInstances; - -// Defines - -// This is the scaling factor that we keep fonts limited to against -// the display size. If a pixel size is requested that is more than -// this factor larger than the height of the display, it's clamped to -// that value instead of the requested size. -#define FONT_MAX_FONT_SCALE 2 - -static NS_DEFINE_CID(kCharsetConverterManagerCID, - NS_ICHARSETCONVERTERMANAGER_CID); - -#ifdef DEBUG -#define DUMP_PRUNICHAR(ustr, ulen) for (PRUint32 llen=0;llen> 6) -#define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \ - MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s)))) - -// Static function decls - -static PangoLanguage *GetPangoLanguage(nsIAtom *aLangGroup); - -static void FreeGlobals (void); - -static PangoStyle CalculateStyle (PRUint8 aStyle); -static PangoWeight CalculateWeight (PRUint16 aWeight); - -static nsresult EnumFontsPango (nsIAtom* aLangGroup, const char* aGeneric, - PRUint32* aCount, PRUnichar*** aResult); -static int CompareFontNames (const void* aArg1, const void* aArg2, - void* aClosure); - -nsFontMetricsPango::nsFontMetricsPango() -{ - if (!gPangoFontLog) - gPangoFontLog = PR_NewLogModule("PangoFont"); - - gNumInstances++; - - mPangoFontDesc = nsnull; - mPangoContext = nsnull; - mLTRPangoContext = nsnull; - mRTLPangoContext = nsnull; - mPangoAttrList = nsnull; - mIsRTL = PR_FALSE; - mPangoSpaceWidth = 0; - - static PRBool initialized = PR_FALSE; - if (initialized) - return; - - // Initialized the custom decoders - if (!mozilla_decoders_init()) - initialized = PR_TRUE; -} - -nsFontMetricsPango::~nsFontMetricsPango() -{ - if (mDeviceContext) - mDeviceContext->FontMetricsDeleted(this); - - if (mPangoFontDesc) - pango_font_description_free(mPangoFontDesc); - - if (mLTRPangoContext) - g_object_unref(mLTRPangoContext); - - if (mRTLPangoContext) - g_object_unref(mRTLPangoContext); - - if (mPangoAttrList) - pango_attr_list_unref(mPangoAttrList); - - // XXX clean up all the pango objects - - if (--gNumInstances == 0) - FreeGlobals(); -} - - -NS_IMPL_ISUPPORTS1(nsFontMetricsPango, nsIFontMetrics) - -// nsIFontMetrics impl - -NS_IMETHODIMP -nsFontMetricsPango::Init(const nsFont& aFont, nsIAtom* aLangGroup, - nsIDeviceContext *aContext) -{ - mFont = aFont; - mLangGroup = aLangGroup; - - // Hang on to the device context - mDeviceContext = aContext; - - mPointSize = NSTwipsToFloatPoints(mFont.size); - - // 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); - - // enumerate over the font names passed in - mFont.EnumerateFamilies(nsFontMetricsPango::EnumFontCallback, this); - - nsCOMPtr prefService; - prefService = do_GetService(NS_PREF_CONTRACTID); - if (!prefService) - return NS_ERROR_FAILURE; - - nsXPIDLCString value; - const char* langGroup; - mLangGroup->GetUTF8String(&langGroup); - - // Set up the default font name if it's not set - if (!mGenericFont) { - nsCAutoString name("font.default."); - name.Append(langGroup); - prefService->CopyCharPref(name.get(), getter_Copies(value)); - - if (value.get()) - mDefaultFont = value.get(); - else - mDefaultFont = "serif"; - - mGenericFont = &mDefaultFont; - } - - // set up the minimum sizes for fonts - if (mLangGroup) { - nsCAutoString name("font.min-size."); - - if (mGenericFont->Equals("monospace")) - name.Append("fixed"); - else - name.Append("variable"); - - name.Append(char('.')); - name.Append(langGroup); - - PRInt32 minimumInt = 0; - float minimum; - nsresult res; - res = prefService->GetIntPref(name.get(), &minimumInt); - if (NS_FAILED(res)) - prefService->GetDefaultIntPref(name.get(), &minimumInt); - - if (minimumInt < 0) - minimumInt = 0; - - minimum = minimumInt; - - // The minimum size is specified in pixels, not in points. - // Convert the size from pixels to points. - minimum = NSTwipsToFloatPoints(NSFloatPixelsToTwips(minimum, mDeviceContext->DevUnitsToAppUnits())); - if (mPointSize < minimum) - mPointSize = minimum; - } - - // Make sure that the pixel size is at least greater than zero - if (mPointSize < 1) { -#ifdef DEBUG - printf("*** Warning: nsFontMetricsPango created with point size %f\n", - mPointSize); -#endif - mPointSize = 1; - } - - nsresult rv = RealizeFont(); - if (NS_FAILED(rv)) - return rv; - - // Cache font metrics for the 'x' character - return CacheFontMetrics(); -} - -nsresult -nsFontMetricsPango::CacheFontMetrics(void) -{ - // Get our scale factor - float f; - float val; - f = mDeviceContext->DevUnitsToAppUnits(); - - mPangoAttrList = pango_attr_list_new(); - - GList *items = pango_itemize(mPangoContext, - "a", 0, 1, mPangoAttrList, NULL); - - if (!items) - return NS_ERROR_FAILURE; - - guint nitems = g_list_length(items); - if (nitems != 1) - return NS_ERROR_FAILURE; - - PangoItem *item = (PangoItem *)items->data; - PangoFcFont *fcfont = PANGO_FC_FONT(item->analysis.font); - if (!fcfont) - return NS_ERROR_FAILURE; - - // Get our font face - FT_Face face; - face = pango_fc_font_lock_face(fcfont); - if (!face) - return NS_ERROR_NOT_AVAILABLE; - - TT_OS2 *os2; - os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2); - - // mEmHeight (size in pixels of EM height) - int size; - if (FcPatternGetInteger(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != - FcResultMatch) { - size = 12; - } - mEmHeight = PR_MAX(1, nscoord(size * f)); - - // mMaxAscent - val = MOZ_FT_TRUNC(face->size->metrics.ascender); - mMaxAscent = NSToIntRound(val * f); - - // mMaxDescent - val = -MOZ_FT_TRUNC(face->size->metrics.descender); - mMaxDescent = NSToIntRound(val * f); - - nscoord lineHeight = mMaxAscent + mMaxDescent; - - // mLeading (needs ascent and descent and EM height) - if (lineHeight > mEmHeight) - mLeading = lineHeight - mEmHeight; - else - mLeading = 0; - - // mMaxHeight (needs ascent and descent) - mMaxHeight = lineHeight; - - // mEmAscent (needs maxascent, EM height, ascent and descent) - mEmAscent = nscoord(mMaxAscent * mEmHeight / lineHeight); - - // mEmDescent (needs EM height and EM ascent - mEmDescent = mEmHeight - mEmAscent; - - // mMaxAdvance - val = MOZ_FT_TRUNC(face->size->metrics.max_advance); - mMaxAdvance = NSToIntRound(val * f); - // X may screw up if we try to measure/draw more than 32767 pixels in - // one operation. - mMaxStringLength = (PRInt32)floor(32767.0/val); - mMaxStringLength = PR_MAX(1, mMaxStringLength); - - // mPangoSpaceWidth - PangoLayout *layout = pango_layout_new(mPangoContext); - pango_layout_set_text(layout, " ", 1); - int pswidth, psheight; - pango_layout_get_size(layout, &pswidth, &psheight); - mPangoSpaceWidth = pswidth; - g_object_unref(layout); - - // mSpaceWidth (width of a space) - nscoord tmpWidth; - GetWidth(" ", 1, tmpWidth, 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); - mAveCharWidth = tmpWidth; - - // mXHeight (height of an 'x' character) - if (pango_fc_font_has_char(fcfont, 'x')) { - PangoRectangle rect; - PangoGlyph glyph = pango_fc_font_get_glyph (fcfont, 'x'); - pango_font_get_glyph_extents (PANGO_FONT (fcfont), glyph, &rect, NULL); - mXHeight = NSToIntRound(rect.height * f / PANGO_SCALE); - } - else { - // 56% of ascent, best guess for non-true type or asian fonts - mXHeight = nscoord(((float)mMaxAscent) * 0.56 * f); - } - - // mUnderlineOffset (offset for underlines) - val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position, - face->size->metrics.y_scale); - if (val) { - mUnderlineOffset = NSToIntRound(val * f); - } - else { - mUnderlineOffset = - -NSToIntRound(PR_MAX(1, floor(0.1 * - MOZ_FT_TRUNC(face->size->metrics.height) + 0.5)) * f); - } - - // mUnderlineSize (thickness of an underline) - val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness, - face->size->metrics.y_scale); - if (val) { - mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(val * f))); - } - else { - mUnderlineSize = - NSToIntRound(PR_MAX(1, - floor(0.05 * MOZ_FT_TRUNC(face->size->metrics.height) + 0.5)) * f); - } - - // mSuperscriptOffset - if (os2 && os2->ySuperscriptYOffset) { - val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset, - face->size->metrics.y_scale); - mSuperscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f))); - } - else { - mSuperscriptOffset = mXHeight; - } - - // mSubscriptOffset - if (os2 && os2->ySubscriptYOffset) { - val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySubscriptYOffset, - face->size->metrics.y_scale); - // some fonts have the incorrect sign. - val = (val < 0) ? -val : val; - mSubscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f))); - } - else { - mSubscriptOffset = mXHeight; - } - - // mStrikeoutOffset - mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0); - - // mStrikeoutSize - mStrikeoutSize = mUnderlineSize; - - pango_fc_font_unlock_face(fcfont); - - /* - printf("%i\n", mXHeight); - printf("%i\n", mSuperscriptOffset); - printf("%i\n", mSubscriptOffset); - printf("%i\n", mStrikeoutOffset); - printf("%i\n", mStrikeoutSize); - printf("%i\n", mUnderlineOffset); - printf("%i\n", mUnderlineSize); - printf("%i\n", mMaxHeight); - printf("%i\n", mLeading); - printf("%i\n", mEmHeight); - printf("%i\n", mEmAscent); - printf("%i\n", mEmDescent); - printf("%i\n", mMaxAscent); - printf("%i\n", mMaxDescent); - printf("%i\n", mMaxAdvance); - printf("%i\n", mSpaceWidth); - printf("%i\n", mAveCharWidth); - */ - - return NS_OK; -} - -NS_IMETHODIMP -nsFontMetricsPango::Destroy() -{ - mDeviceContext = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsFontMetricsPango::GetLangGroup(nsIAtom** aLangGroup) -{ - *aLangGroup = mLangGroup; - NS_IF_ADDREF(*aLangGroup); - - return NS_OK; -} - -NS_IMETHODIMP -nsFontMetricsPango::GetFontHandle(nsFontHandle &aHandle) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -// nsIFontMetricsPango impl - -nsresult -nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength, - nscoord& aWidth, - nsRenderingContextGTK *aContext) -{ - PangoLayout *layout = pango_layout_new(mPangoContext); - - pango_layout_set_text(layout, aString, aLength); - - if (mPangoSpaceWidth) - FixupSpaceWidths(layout, aString); - - int width, height; - - pango_layout_get_size(layout, &width, &height); - - g_object_unref(layout); - - float f; - 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) -{ - 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); - pango_layout_get_size(layout, &width, &height); - - float f; - f = mDeviceContext->DevUnitsToAppUnits(); - aWidth = NSToCoordRound(width * f / PANGO_SCALE); - - // printf("GetWidth %d\n", aWidth); - - loser: - g_free(text); - g_object_unref(layout); - - return rv; -} - - -nsresult -nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - nsresult rv = NS_OK; - - PangoLayout *layout = pango_layout_new(mPangoContext); - - 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; - } - - - pango_layout_set_text(layout, text, strlen(text)); - FixupSpaceWidths(layout, text); - - // 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); - - PangoRectangle rect; - pango_layout_line_get_extents(line, NULL, &rect); - - float P2T; - P2T = mDeviceContext->DevUnitsToAppUnits(); - - 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); - - // printf("GetTextDimensions %d %d %d\n", aDimensions.width, - //aDimensions.ascent, aDimensions.descent); - - loser: - g_free(text); - g_object_unref(layout); - - return rv; -} - -nsresult -nsFontMetricsPango::GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - - return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks, - aNumBreaks, aDimensions, aNumCharsFit, - aLastWordDimensions, aContext); - -} - -nsresult -nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - nsresult rv = NS_OK; - PRInt32 curBreak = 0; - gchar *curChar; - - PRInt32 *utf8Breaks = new PRInt32[aNumBreaks]; - - gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength, - NULL, NULL, NULL); - - 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)) { - if (aBreaks[curBreak] == curOffset) { - utf8Breaks[curBreak] = curChar - text; - curBreak++; - } - - if (NS_IS_HIGH_SURROGATE(aString[curOffset])) - curOffset++; - } - - // Always catch the last break - utf8Breaks[curBreak] = curChar - text; - -#if 0 - if (strlen(text) != aLength) { - printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text)); - DUMP_PRUNICHAR(aString, aLength) - DUMP_PRUNICHAR(text, strlen(text)) - for (PRInt32 i = 0; i < aNumBreaks; ++i) { - printf(" break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]); - } - } -#endif - - // 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, - aNumBreaks, aDimensions, aNumCharsFit, - aLastWordDimensions, aContext); - - // Figure out which of the breaks we ended up using to convert - // back to utf16 - start from the end. - for (PRInt32 i = aNumBreaks - 1; i >= 0; --i) { - if (utf8Breaks[i] == aNumCharsFit) { - // if (aNumCharsFit != aBreaks[i]) - // printf("Fixing utf8 -> utf16 %d -> %d\n", aNumCharsFit, aBreaks[i]); - aNumCharsFit = aBreaks[i]; - break; - } - } - - loser: - if (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) -{ - PangoLayout *layout = pango_layout_new(mPangoContext); - - pango_layout_set_text(layout, aString, aLength); - FixupSpaceWidths(layout, aString); - - int x = aX; - int y = aY; - - aContext->GetTranMatrix()->TransformCoord(&x, &y); - - PangoLayoutLine *line; - if (pango_layout_get_line_count(layout) != 1) { - printf("Warning: more than one line!\n"); - } - line = pango_layout_get_line(layout, 0); - - aContext->UpdateGC(); - GdkGC *gc = aContext->GetGC(); - - 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); - } - - g_object_unref(gc); - g_object_unref(layout); - - // printf("DrawString (char *)\n"); - - return NS_OK; -} - -nsresult -nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface) -{ - nsresult rv = NS_OK; - int x = aX; - int y = aY; - - aContext->UpdateGC(); - GdkGC *gc = aContext->GetGC(); - - PangoLayout *layout = pango_layout_new(mPangoContext); - - gchar *text = g_utf16_to_utf8(aString, aLength, - NULL, NULL, NULL); - - if (!text) { -#ifdef DEBUG - NS_WARNING("nsFontMetricsPango::DrawString invalid unicode to follow"); - DUMP_PRUNICHAR(aString, aLength) -#endif - rv = NS_ERROR_FAILURE; - goto loser; - } - - pango_layout_set_text(layout, text, strlen(text)); - FixupSpaceWidths(layout, text); - - aContext->GetTranMatrix()->TransformCoord(&x, &y); - - PangoLayoutLine *line; - if (pango_layout_get_line_count(layout) != 1) { - printf("Warning: more than one line!\n"); - } - line = pango_layout_get_line(layout, 0); - - 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); - } - - loser: - - g_free(text); - g_object_unref(gc); - g_object_unref(layout); - - // printf("DrawString\n"); - - return rv; -} - -#ifdef MOZ_MATHML -nsresult -nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - nsRenderingContextGTK *aContext) -{ - printf("GetBoundingMetrics (char *)\n"); - return NS_ERROR_FAILURE; -} - -nsresult -nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - PRInt32 *aFontID, - nsRenderingContextGTK *aContext) -{ - nsresult rv = NS_OK; - PangoLayout *layout = pango_layout_new(mPangoContext); - - gchar *text = g_utf16_to_utf8(aString, aLength, - NULL, NULL, NULL); - - if (!text) { -#ifdef DEBUG - NS_WARNING("nsFontMetricsPango::GetBoundingMetrics invalid unicode to follow"); - DUMP_PRUNICHAR(aString, aLength) -#endif - aBoundingMetrics.Clear(); - - rv = NS_ERROR_FAILURE; - goto loser; - } - - pango_layout_set_text(layout, text, -1); - FixupSpaceWidths(layout, text); - - PangoLayoutLine *line; - if (pango_layout_get_line_count(layout) != 1) { - printf("Warning: more than one line!\n"); - } - line = pango_layout_get_line(layout, 0); - - // Get the ink and logical extents - PangoRectangle ink, logical; - pango_layout_line_get_extents(line, &ink, &logical); - - float P2T; - 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); - g_object_unref(layout); - - return rv; -} - -#endif /* MOZ_MATHML */ - -GdkFont* -nsFontMetricsPango::GetCurrentGDKFont(void) -{ - return nsnull; -} - -nsresult -nsFontMetricsPango::SetRightToLeftText(PRBool aIsRTL) -{ - if (aIsRTL) { - if (!mRTLPangoContext) { - mRTLPangoContext = gdk_pango_context_get(); - 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); - } - mPangoContext = mRTLPangoContext; - } - else { - mPangoContext = mLTRPangoContext; - } - - mIsRTL = aIsRTL; - return NS_OK; -} - -PRBool -nsFontMetricsPango::GetRightToLeftText() -{ - return mIsRTL; -} - -nsresult -nsFontMetricsPango::GetClusterInfo(const PRUnichar *aText, - 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); - - // 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 (NS_IS_HIGH_SURROGATE(aText[pos])) { - aClusterStarts[pos] = 1; - pos++; - } - else { - aClusterStarts[pos] = attrs[pos].is_cursor_position; - } - } - - loser: - if (attrs) - g_free(attrs); - if (text) - g_free(text); - if (layout) - g_object_unref(layout); - - return rv; -} - -PRInt32 -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); - - pango_layout_xy_to_index(layout, localX, localY, - &inx, &trailing); - - // Convert the index back to the utf-16 index - curChar = text; - - for (PRUint32 curOffset=0; curOffset < aLength; - curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) { - - // Check for a match before checking for a surrogate pair - if (curChar - text == inx) { - retval = curOffset; - break; - } - - if (NS_IS_HIGH_SURROGATE(aText[curOffset])) - curOffset++; - } - - // If there was a trailing result, advance the index pointer the - // number of characters equal to the trailing result. - while (trailing) { - retval++; - // Yes, this can make aInx > length to indicate the end of the - // string. - if (retval < (PRInt32)aLength && NS_IS_HIGH_SURROGATE(aText[retval])) - retval++; - trailing--; - } - - loser: - if (text) - g_free(text); - if (layout) - g_object_unref(layout); - - return retval; -} - -nsresult -nsFontMetricsPango::GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - 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; - } - - // Convert the utf16 offsets into utf8 offsets - for (PRUint32 curOffset = 0; curOffset < aLength; - curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) { - - if (curOffset == aStart) - utf8Start = curChar - text; - - if (curOffset == aEnd) - utf8End = curChar - text; - - if (NS_IS_HIGH_SURROGATE(aText[curOffset])) - curOffset++; - } - - // Special case where the end index is the same as the length - if (aLength == aEnd) - utf8End = strlen(text); - - rv = GetRangeWidth(text, strlen(text), utf8Start, utf8End, aWidth); - - loser: - if (text) - g_free(text); - - return rv; -} - -nsresult -nsFontMetricsPango::GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - 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); - - 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); - - loser: - if (ranges) - g_free(ranges); - if (layout) - g_object_unref(layout); - - return rv; -} - -/* static */ -PRUint32 -nsFontMetricsPango::GetHints(void) -{ - return (NS_RENDERING_HINT_BIDI_REORDERING | - NS_RENDERING_HINT_ARABIC_SHAPING | - NS_RENDERING_HINT_FAST_MEASURE | - NS_RENDERING_HINT_REORDER_SPACED_TEXT | - NS_RENDERING_HINT_TEXT_CLUSTERS); -} - -/* static */ -nsresult -nsFontMetricsPango::FamilyExists(nsIDeviceContext *aDevice, - const nsString &aName) -{ - // fontconfig family name is always in UTF-8 - NS_ConvertUTF16toUTF8 name(aName); - - nsresult rv = NS_ERROR_FAILURE; - PangoContext *context = gdk_pango_context_get(); - PangoFontFamily **familyList; - int n; - - pango_context_list_families(context, &familyList, &n); - - for (int i=0; i < n; i++) { - const char *tmpname = pango_font_family_get_name(familyList[i]); - if (!Compare(nsDependentCString(tmpname), name, - nsCaseInsensitiveCStringComparator())) { - rv = NS_OK; - break; - } - } - - g_free(familyList); - g_object_unref(context); - - return rv; -} - -// Private Methods - -nsresult -nsFontMetricsPango::RealizeFont(void) -{ - nsCString familyList; - // Create and fill out the font description. - mPangoFontDesc = pango_font_description_new(); - - // Add CSS names - walk the list of fonts, adding the generic as - // the last font - for (int i=0; i < mFontList.Count(); ++i) { - // if this was a generic name, break out of the loop since we - // don't want to add it to the pattern yet - if (mFontIsGeneric[i]) - break;; - - nsCString *familyName = mFontList.CStringAt(i); - familyList.Append(familyName->get()); - familyList.Append(','); - } - - // If there's a generic add a pref for the generic if there's one - // set. - if (mGenericFont && !mFont.systemFont) { - nsCString name; - name += "font.name."; - name += mGenericFont->get(); - name += "."; - - nsString langGroup; - mLangGroup->ToString(langGroup); - - name.AppendWithConversion(langGroup); - - nsCOMPtr pref; - pref = do_GetService(NS_PREF_CONTRACTID); - if (pref) { - nsresult rv; - nsXPIDLCString value; - rv = pref->GetCharPref(name.get(), getter_Copies(value)); - - // we ignore prefs that have three hypens since they are X - // style prefs. - if (NS_FFRECountHyphens(value) < 3) { - nsCString tmpstr; - tmpstr.Append(value); - - familyList.Append(tmpstr); - familyList.Append(','); - } - } - } - - // Add the generic if there is one. - if (mGenericFont && !mFont.systemFont) { - familyList.Append(mGenericFont->get()); - familyList.Append(','); - } - - // Set the family - pango_font_description_set_family(mPangoFontDesc, - familyList.get()); - - // Set the point size - pango_font_description_set_size(mPangoFontDesc, - (gint)(mPointSize * PANGO_SCALE)); - - // Set the style - pango_font_description_set_style(mPangoFontDesc, - CalculateStyle(mFont.style)); - - // Set the weight - pango_font_description_set_weight(mPangoFontDesc, - CalculateWeight(mFont.weight)); - - // Now that we have the font description set up, create the - // context. - mLTRPangoContext = gdk_pango_context_get(); - 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)); - - // And attach the font description to this context - pango_context_set_font_description(mPangoContext, mPangoFontDesc); - - return NS_OK; -} - -/* static */ -PRBool -nsFontMetricsPango::EnumFontCallback(const nsString &aFamily, - PRBool aIsGeneric, void *aData) -{ - NS_ConvertUTF16toUTF8 name(aFamily); - - // The newest fontconfig does the full Unicode case folding so that - // we're being lazy here by calling |ToLowerCase| after converting - // to UTF-8 assuming that in virtually all cases, we just have to - // fold [A-Z]. (bug 223653). - ToLowerCase(name); - nsFontMetricsPango *metrics = (nsFontMetricsPango *)aData; - metrics->mFontList.AppendCString(name); - metrics->mFontIsGeneric.AppendElement((void *)aIsGeneric); - if (aIsGeneric) { - metrics->mGenericFont = - metrics->mFontList.CStringAt(metrics->mFontList.Count() - 1); - return PR_FALSE; // stop processing - } - - return PR_TRUE; // keep processing -} - -/* - * 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! - */ - -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; - - /* - * 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. - */ - nscoord *utf8spacing = new nscoord[strlen(aText)]; - - 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 (NS_IS_HIGH_SURROGATE(aOrigString[curOffset])) - curOffset++; - } - } - else { - memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength)); - } - - gint curRun = 0; - - for (GSList *tmpList = aLine->runs; tmpList && tmpList->data; - tmpList = tmpList->next, curRun++) { - PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data; - gint tmpOffset = 0; - - /* printf(" Rendering run %d: \"%s\"\n", curRun, - &aText[layoutRun->item->offset]); */ - - 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; - } - - /* printf(" rendering at X coord %d\n", aX + offset); */ - offset += tmpOffset; - } - - gdk_draw_layout_line(aDrawable, aGC, aX, aY, aLine); - - delete[] utf8spacing; -} - -nsresult -nsFontMetricsPango::GetTextDimensionsInternal(const gchar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - nsRenderingContextGTK *aContext) -{ - NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array"); - - // If we need to back up this state represents the last place - // we could break. We can use this to avoid remeasuring text - PRInt32 prevBreakState_BreakIndex = -1; // not known - // (hasn't been computed) - nscoord prevBreakState_Width = 0; // accumulated width to this point - - // Initialize OUT parameters - GetMaxAscent(aLastWordDimensions.ascent); - GetMaxDescent(aLastWordDimensions.descent); - aLastWordDimensions.width = -1; - aNumCharsFit = 0; - - // Iterate each character in the string and determine which font to use - nscoord width = 0; - PRInt32 start = 0; - nscoord aveCharWidth; - GetAveCharWidth(aveCharWidth); - - while (start < aLength) { - // Estimate how many characters will fit. Do that by - // diving the available space by the average character - // width. Make sure the estimated number of characters is - // at least 1 - PRInt32 estimatedNumChars = 0; - - if (aveCharWidth > 0) - estimatedNumChars = (aAvailWidth - width) / aveCharWidth; - - if (estimatedNumChars < 1) - estimatedNumChars = 1; - - // Find the nearest break offset - PRInt32 estimatedBreakOffset = start + estimatedNumChars; - PRInt32 breakIndex; - nscoord numChars; - - // Find the nearest place to break that is less than or equal to - // the estimated break offset - if (aLength <= estimatedBreakOffset) { - // All the characters should fit - numChars = aLength - start; - breakIndex = aNumBreaks - 1; - } - else { - breakIndex = prevBreakState_BreakIndex; - while (((breakIndex + 1) < aNumBreaks) && - (aBreaks[breakIndex + 1] <= estimatedBreakOffset)) { - ++breakIndex; - } - - if (breakIndex == prevBreakState_BreakIndex) { - ++breakIndex; // make sure we advanced past the - // previous break index - } - - numChars = aBreaks[breakIndex] - start; - } - - // Measure the text - nscoord twWidth = 0; - if ((1 == numChars) && (aString[start] == ' ')) - GetSpaceWidth(twWidth); - else if (numChars > 0) - GetWidth(&aString[start], numChars, twWidth, aContext); - - // See if the text fits - PRBool textFits = (twWidth + width) <= aAvailWidth; - - // If the text fits then update the width and the number of - // characters that fit - if (textFits) { - aNumCharsFit += numChars; - width += twWidth; - start += numChars; - - // This is a good spot to back up to if we need to so remember - // this state - prevBreakState_BreakIndex = breakIndex; - prevBreakState_Width = width; - } - else { - // See if we can just back up to the previous saved - // state and not have to measure any text - if (prevBreakState_BreakIndex > 0) { - // If the previous break index is just before the - // current break index then we can use it - if (prevBreakState_BreakIndex == (breakIndex - 1)) { - aNumCharsFit = aBreaks[prevBreakState_BreakIndex]; - width = prevBreakState_Width; - break; - } - } - - // We can't just revert to the previous break state - if (0 == breakIndex) { - // There's no place to back up to, so even though - // the text doesn't fit return it anyway - aNumCharsFit += numChars; - width += twWidth; - break; - } - - // Repeatedly back up until we get to where the text - // fits or we're all the way back to the first word - width += twWidth; - while ((breakIndex >= 1) && (width > aAvailWidth)) { - twWidth = 0; - start = aBreaks[breakIndex - 1]; - numChars = aBreaks[breakIndex] - start; - - if ((1 == numChars) && (aString[start] == ' ')) - GetSpaceWidth(twWidth); - else if (numChars > 0) - GetWidth(&aString[start], numChars, twWidth, - aContext); - width -= twWidth; - aNumCharsFit = start; - breakIndex--; - } - break; - } - } - - aDimensions.width = width; - GetMaxAscent(aDimensions.ascent); - GetMaxDescent(aDimensions.descent); - - /* printf("aDimensions %d %d %d aLastWordDimensions %d %d %d aNumCharsFit %d\n", - aDimensions.width, aDimensions.ascent, aDimensions.descent, - aLastWordDimensions.width, aLastWordDimensions.ascent, aLastWordDimensions.descent, - aNumCharsFit); */ - - return NS_OK; -} - -void -nsFontMetricsPango::FixupSpaceWidths (PangoLayout *aLayout, - const char *aString) -{ - PangoLayoutLine *line = pango_layout_get_line(aLayout, 0); - - gint curRun = 0; - - for (GSList *tmpList = line->runs; tmpList && tmpList->data; - tmpList = tmpList->next, curRun++) { - PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data; - - for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) { - gint thisOffset = (gint)layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset; - if (aString[thisOffset] == ' ') - layoutRun->glyphs->glyphs[i].geometry.width = mPangoSpaceWidth; - } - } -} - -/* static */ -PangoLanguage * -GetPangoLanguage(nsIAtom *aLangGroup) -{ - // Find the FC lang group for this lang group - nsCAutoString cname; - aLangGroup->ToUTF8String(cname); - - // see if the lang group needs to be translated from mozilla's - // internal mapping into fontconfig's - const MozGtkLangGroup *langGroup; - langGroup = NS_FindFCLangGroup(cname); - - // if there's no lang group, just use the lang group as it was - // passed to us - // - // we're casting away the const here for the strings - should be - // safe. - if (!langGroup) - return pango_language_from_string(cname.get()); - else if (langGroup->Lang) - return pango_language_from_string((char *) langGroup->Lang); - - return pango_language_from_string("en"); -} - -/* static */ -void -FreeGlobals(void) -{ -} - -/* static */ -PangoStyle -CalculateStyle(PRUint8 aStyle) -{ - switch(aStyle) { - case NS_FONT_STYLE_ITALIC: - return PANGO_STYLE_ITALIC; - break; - case NS_FONT_STYLE_OBLIQUE: - return PANGO_STYLE_OBLIQUE; - break; - } - - return PANGO_STYLE_NORMAL; -} - -/* static */ -PangoWeight -CalculateWeight (PRUint16 aWeight) -{ - /* - * weights come in two parts crammed into one - * integer -- the "base" weight is weight / 100, - * the rest of the value is the "offset" from that - * weight -- the number of steps to move to adjust - * the weight in the list of supported font weights, - * this value can be negative or positive. - */ - PRInt32 baseWeight = (aWeight + 50) / 100; - PRInt32 offset = aWeight - baseWeight * 100; - - /* clip weights to range 0 to 9 */ - if (baseWeight < 0) - baseWeight = 0; - if (baseWeight > 9) - baseWeight = 9; - - /* Map from weight value to fcWeights index */ - static int fcWeightLookup[10] = { - 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, - }; - - PRInt32 fcWeight = fcWeightLookup[baseWeight]; - - /* - * adjust by the offset value, make sure we stay inside the - * fcWeights table - */ - fcWeight += offset; - - if (fcWeight < 0) - fcWeight = 0; - if (fcWeight > 4) - fcWeight = 4; - - /* Map to final PANGO_WEIGHT value */ - static int fcWeights[5] = { - 349, - 499, - 649, - 749, - 999 - }; - - return (PangoWeight)fcWeights[fcWeight]; -} - -/* static */ -nsresult -EnumFontsPango(nsIAtom* aLangGroup, const char* aGeneric, - PRUint32* aCount, PRUnichar*** aResult) -{ - FcPattern *pat = NULL; - FcObjectSet *os = NULL; - FcFontSet *fs = NULL; - nsresult rv = NS_ERROR_FAILURE; - - PRUnichar **array = NULL; - PRUint32 narray = 0; - PRInt32 serif = 0, sansSerif = 0, monospace = 0, nGenerics; - - *aCount = 0; - *aResult = nsnull; - - pat = FcPatternCreate(); - if (!pat) - goto end; - - os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, NULL); - if (!os) - goto end; - - // take the pattern and add the lang group to it - if (aLangGroup) - NS_AddLangGroup(pat, aLangGroup); - - // get the font list - fs = FcFontList(0, pat, os); - - if (!fs) - goto end; - - if (!fs->nfont) { - rv = NS_OK; - goto end; - } - - // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and - // "monospace", slightly different from CSS's 5. - if (!aGeneric) - serif = sansSerif = monospace = 1; - else if (!strcmp(aGeneric, "serif")) - serif = 1; - else if (!strcmp(aGeneric, "sans-serif")) - sansSerif = 1; - else if (!strcmp(aGeneric, "monospace")) - monospace = 1; - else if (!strcmp(aGeneric, "cursive") || !strcmp(aGeneric, "fantasy")) - serif = sansSerif = 1; - else - NS_NOTREACHED("unexpected generic family"); - nGenerics = serif + sansSerif + monospace; - - array = NS_STATIC_CAST(PRUnichar **, - nsMemory::Alloc((fs->nfont + nGenerics) * sizeof(PRUnichar *))); - if (!array) - goto end; - - if (serif) { - PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("serif")); - if (!name) - goto end; - array[narray++] = name; - } - - if (sansSerif) { - PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("sans-serif")); - if (!name) - goto end; - array[narray++] = name; - } - - if (monospace) { - PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("monospace")); - if (!name) - goto end; - array[narray++] = name; - } - - for (int i=0; i < fs->nfont; ++i) { - char *family; - - // if there's no family, just move to the next iteration - if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0, - (FcChar8 **) &family) != FcResultMatch) { - continue; - } - - // fontconfig always returns family names in UTF-8 - PRUnichar* name = UTF8ToNewUnicode(nsDependentCString(family)); - - if (!name) - goto end; - - array[narray++] = name; - } - - NS_QuickSort(array + nGenerics, narray - nGenerics, sizeof (PRUnichar*), - CompareFontNames, nsnull); - - *aCount = narray; - if (narray) - *aResult = array; - else - nsMemory::Free(array); - - rv = NS_OK; - - end: - if (NS_FAILED(rv) && array) { - while (narray) - nsMemory::Free (array[--narray]); - nsMemory::Free (array); - } - if (pat) - FcPatternDestroy(pat); - if (os) - FcObjectSetDestroy(os); - if (fs) - FcFontSetDestroy(fs); - - return rv; -} - -/* static */ -int -CompareFontNames (const void* aArg1, const void* aArg2, void* aClosure) -{ - const PRUnichar* str1 = *((const PRUnichar**) aArg1); - const PRUnichar* str2 = *((const PRUnichar**) aArg2); - - return nsCRT::strcmp(str1, str2); -} - - -// nsFontEnumeratorPango class - -nsFontEnumeratorPango::nsFontEnumeratorPango() -{ -} - -NS_IMPL_ISUPPORTS1(nsFontEnumeratorPango, nsIFontEnumerator) - -NS_IMETHODIMP -nsFontEnumeratorPango::EnumerateAllFonts(PRUint32 *aCount, - PRUnichar ***aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - NS_ENSURE_ARG_POINTER(aCount); - *aCount = 0; - - return EnumFontsPango(nsnull, nsnull, aCount, aResult); -} - -NS_IMETHODIMP -nsFontEnumeratorPango::EnumerateFonts(const char *aLangGroup, - const char *aGeneric, - PRUint32 *aCount, - PRUnichar ***aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - NS_ENSURE_ARG_POINTER(aCount); - *aCount = 0; - - // aLangGroup=null or "" means any (i.e., don't care) - // aGeneric=null or "" means any (i.e, don't care) - nsCOMPtr langGroup; - if (aLangGroup && *aLangGroup) - langGroup = do_GetAtom(aLangGroup); - const char* generic = nsnull; - if (aGeneric && *aGeneric) - generic = aGeneric; - - return EnumFontsPango(langGroup, generic, aCount, aResult); -} - -NS_IMETHODIMP -nsFontEnumeratorPango::HaveFontFor(const char *aLangGroup, - PRBool *aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = PR_FALSE; - NS_ENSURE_ARG_POINTER(aLangGroup); - - *aResult = PR_TRUE; // always return true for now. - // Finish me - ftang - return NS_OK; -} - -NS_IMETHODIMP -nsFontEnumeratorPango::GetDefaultFont(const char *aLangGroup, - const char *aGeneric, - PRUnichar **aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - - // Have a look at nsFontEnumeratorXft::GetDefaultFont for some - // possible code for this function. - - return NS_OK; -} - -NS_IMETHODIMP -nsFontEnumeratorPango::UpdateFontList(PRBool *_retval) -{ - *_retval = PR_FALSE; // always return false for now - return NS_OK; -} diff --git a/gfx/src/gtk/nsFontMetricsPango.h b/gfx/src/gtk/nsFontMetricsPango.h deleted file mode 100644 index 743899109f6d..000000000000 --- a/gfx/src/gtk/nsFontMetricsPango.h +++ /dev/null @@ -1,304 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard . - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsIFontMetrics.h" -#include "nsIFontEnumerator.h" -#include "nsCRT.h" -#include "nsIAtom.h" -#include "nsString.h" -#include "nsVoidArray.h" -#include "nsIFontMetricsGTK.h" - -#include - -class nsFontMetricsPango : public nsIFontMetricsGTK -{ -public: - nsFontMetricsPango(); - virtual ~nsFontMetricsPango(); - - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - // nsISupports - NS_DECL_ISUPPORTS - - // nsIFontMetrics - NS_IMETHOD Init (const nsFont& aFont, nsIAtom* aLangGroup, - nsIDeviceContext *aContext); - NS_IMETHOD Destroy(); - NS_IMETHOD GetLangGroup (nsIAtom** aLangGroup); - NS_IMETHOD GetFontHandle (nsFontHandle &aHandle); - - NS_IMETHOD GetXHeight (nscoord& aResult) - { aResult = mXHeight; return NS_OK; }; - - NS_IMETHOD GetSuperscriptOffset (nscoord& aResult) - { aResult = mSuperscriptOffset; - return NS_OK; }; - - NS_IMETHOD GetSubscriptOffset (nscoord& aResult) - { aResult = mSubscriptOffset; - return NS_OK; }; - - NS_IMETHOD GetStrikeout (nscoord& aOffset, nscoord& aSize) - { aOffset = mStrikeoutOffset; - aSize = mStrikeoutSize; - return NS_OK; }; - - NS_IMETHOD GetUnderline (nscoord& aOffset, nscoord& aSize) - { aOffset = mUnderlineOffset; - aSize = mUnderlineSize; - return NS_OK; }; - - NS_IMETHOD GetHeight (nscoord &aHeight) - { aHeight = mMaxHeight; - return NS_OK; }; - - NS_IMETHOD GetNormalLineHeight (nscoord &aHeight) - { aHeight = mEmHeight + mLeading; - return NS_OK; }; - - NS_IMETHOD GetLeading (nscoord &aLeading) - { aLeading = mLeading; - return NS_OK; }; - - NS_IMETHOD GetEmHeight (nscoord &aHeight) - { aHeight = mEmHeight; - return NS_OK; }; - - NS_IMETHOD GetEmAscent (nscoord &aAscent) - { aAscent = mEmAscent; - return NS_OK; }; - - NS_IMETHOD GetEmDescent (nscoord &aDescent) - { aDescent = mEmDescent; - return NS_OK; }; - - NS_IMETHOD GetMaxHeight (nscoord &aHeight) - { aHeight = mMaxHeight; - return NS_OK; }; - - NS_IMETHOD GetMaxAscent (nscoord &aAscent) - { aAscent = mMaxAscent; - return NS_OK; }; - - NS_IMETHOD GetMaxDescent (nscoord &aDescent) - { aDescent = mMaxDescent; - return NS_OK; }; - - NS_IMETHOD GetMaxAdvance (nscoord &aAdvance) - { aAdvance = mMaxAdvance; - return NS_OK; }; - - NS_IMETHOD GetSpaceWidth (nscoord &aSpaceCharWidth) - { aSpaceCharWidth = mSpaceWidth; - return NS_OK; }; - - NS_IMETHOD GetAveCharWidth (nscoord &aAveCharWidth) - { aAveCharWidth = mAveCharWidth; - return NS_OK; }; - - 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); - - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - virtual nsresult GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - - virtual nsresult 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, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface); - -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - nsRenderingContextGTK *aContext); - virtual nsresult GetBoundingMetrics(const PRUnichar *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - PRInt32 *aFontID, - nsRenderingContextGTK *aContext); -#endif /* MOZ_MATHML */ - - virtual GdkFont* GetCurrentGDKFont(void); - - virtual nsresult SetRightToLeftText(PRBool aIsRTL); - virtual PRBool GetRightToLeftText(); - - virtual nsresult GetClusterInfo(const PRUnichar *aText, - PRUint32 aLength, - PRUint8 *aClusterStarts); - - virtual PRInt32 GetPosition(const PRUnichar *aText, - PRUint32 aLength, - nsPoint aPt); - - virtual nsresult GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - - virtual nsresult GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - - // get hints for the font - static 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 mLangGroup; - nsCString *mGenericFont; - float mPointSize; - - nsCAutoString mDefaultFont; - - // Pango-related items - PangoFontDescription *mPangoFontDesc; - PangoContext *mPangoContext; - PangoContext *mLTRPangoContext; - PangoContext *mRTLPangoContext; - PangoAttrList *mPangoAttrList; - PRBool mIsRTL; - - // Cached font metrics - nscoord mXHeight; - nscoord mSuperscriptOffset; - nscoord mSubscriptOffset; - nscoord mStrikeoutOffset; - nscoord mStrikeoutSize; - nscoord mUnderlineOffset; - nscoord mUnderlineSize; - nscoord mMaxHeight; - nscoord mLeading; - nscoord mEmHeight; - nscoord mEmAscent; - nscoord mEmDescent; - nscoord mMaxAscent; - nscoord mMaxDescent; - nscoord mMaxAdvance; - nscoord mSpaceWidth; - nscoord mPangoSpaceWidth; - nscoord mAveCharWidth; - PRInt32 mMaxStringLength; - - // Private methods - nsresult RealizeFont(void); - nsresult CacheFontMetrics(void); - - 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); - - nsresult GetTextDimensionsInternal(const gchar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - nsRenderingContextGTK *aContext); - - void FixupSpaceWidths (PangoLayout *aLayout, const char *aString); -}; - -class nsFontEnumeratorPango : public nsIFontEnumerator -{ -public: - nsFontEnumeratorPango(); - NS_DECL_ISUPPORTS - NS_DECL_NSIFONTENUMERATOR -}; diff --git a/gfx/src/gtk/nsFontMetricsUtils.cpp b/gfx/src/gtk/nsFontMetricsUtils.cpp deleted file mode 100644 index 2bcd76924198..000000000000 --- a/gfx/src/gtk/nsFontMetricsUtils.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard . - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -// welcome to the dumping ground for font metrics stuff that has to -// know about both the xft and core fonts code. - -#ifdef MOZ_ENABLE_XFT -#include "nsFontMetricsXft.h" -#include "nsIPref.h" -#include "nsServiceManagerUtils.h" -#include "prenv.h" -#endif /* MOZ_ENABLE_XFT */ - -#ifdef MOZ_ENABLE_COREXFONTS -#include "nsFontMetricsGTK.h" -#endif - -#ifdef MOZ_ENABLE_PANGO -#include "nsFontMetricsPango.h" -#include "prenv.h" -#endif - -#include "nsFontMetricsUtils.h" - -PRUint32 -NS_FontMetricsGetHints(void) -{ -#ifdef MOZ_ENABLE_PANGO - if (NS_IsPangoEnabled()) { - return nsFontMetricsPango::GetHints(); - } -#endif -#ifdef MOZ_ENABLE_XFT - if (NS_IsXftEnabled()) { - return nsFontMetricsXft::GetHints(); - } -#endif - -#ifdef MOZ_ENABLE_COREXFONTS - return nsFontMetricsGTK::GetHints(); -#endif -} - -nsresult -NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice, const nsString &aName) -{ -#ifdef MOZ_ENABLE_PANGO - if (NS_IsPangoEnabled()) { - return nsFontMetricsPango::FamilyExists(aDevice, aName); - } -#endif -#ifdef MOZ_ENABLE_XFT - // try to fall through to the core fonts if xft fails - if (NS_IsXftEnabled()) { - return nsFontMetricsXft::FamilyExists(aDevice, aName); - } -#endif - -#ifdef MOZ_ENABLE_COREXFONTS - return nsFontMetricsGTK::FamilyExists(aDevice, aName); -#endif -} - -#if defined(MOZ_ENABLE_XFT) && defined(MOZ_ENABLE_COREXFONTS) - -PRBool -NS_IsXftEnabled(void) -{ - static PRBool been_here = PR_FALSE; - static PRBool cachedXftSetting = PR_TRUE; - - if (!been_here) { - been_here = PR_TRUE; - nsCOMPtr prefService; - prefService = do_GetService(NS_PREF_CONTRACTID); - if (!prefService) - return PR_TRUE; - - nsresult rv; - - rv = prefService->GetBoolPref("fonts.xft.enabled", &cachedXftSetting); - - // Yes, this makes sense. If xft is compiled in and there's no - // pref, it's automatically enabled. If there's no pref, check - // the environment. - if (NS_FAILED(rv)) { - char *val = PR_GetEnv("GDK_USE_XFT"); - - if (val && val[0] == '0') { - cachedXftSetting = PR_FALSE; - goto end; - } - - cachedXftSetting = PR_TRUE; - } - } - - end: - - return cachedXftSetting; -} - -#endif - -#if defined(MOZ_ENABLE_PANGO) && (defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_COREXFONTS)) - -PRBool -NS_IsPangoEnabled(void) -{ - char *val = PR_GetEnv("MOZ_DISABLE_PANGO"); - if (val) - return FALSE; - - return TRUE; -} - -#endif diff --git a/gfx/src/gtk/nsFontMetricsUtils.h b/gfx/src/gtk/nsFontMetricsUtils.h deleted file mode 100644 index c0b08a26b568..000000000000 --- a/gfx/src/gtk/nsFontMetricsUtils.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard . - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nsFontMetricsUtils_h -#define __nsFontMetricsUtils_h - -extern PRUint32 NS_FontMetricsGetHints (); -extern nsresult NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice, - const nsString &aName); -#ifdef MOZ_ENABLE_XFT -#ifdef MOZ_ENABLE_COREXFONTS -extern PRBool NS_IsXftEnabled(); -#else -inline PRBool NS_IsXftEnabled() { return PR_TRUE; } -#endif -#endif - -#ifdef MOZ_ENABLE_PANGO -#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_COREXFONTS) -extern PRBool NS_IsPangoEnabled(); -#else -inline PRBool NS_IsPangoEnabled() { return PR_TRUE; } -#endif -#endif - -#endif /* __nsFontMetricsUtils_h */ diff --git a/gfx/src/gtk/nsFontMetricsXft.cpp b/gfx/src/gtk/nsFontMetricsXft.cpp deleted file mode 100644 index 7cf666cf3bbf..000000000000 --- a/gfx/src/gtk/nsFontMetricsXft.cpp +++ /dev/null @@ -1,2719 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Christopher Blizzard - * . Portions created by the Initial Developer - * are Copyright (C) 2002 the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Pierre Phaneuf - * Roland Mainz - * Brian Stell - * Morten Nilsen - * Jungshik Shin - * Jim Nance - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsISupportsUtils.h" -#include "nsServiceManagerUtils.h" -#include "nsIPref.h" -#include "nsFontMetricsXft.h" -#include "prenv.h" -#include "prprf.h" -#include "prlink.h" -#include "nsQuickSort.h" -#include "nsFont.h" -#include "nsIDeviceContext.h" -#include "nsRenderingContextGTK.h" -#include "nsDeviceContextGTK.h" -#include "nsReadableUtils.h" -#include "nsUnicharUtils.h" -#include "nsITimelineService.h" -#include "nsICharsetConverterManager.h" -#include "nsICharRepresentable.h" -#include "nsIPersistentProperties2.h" -#include "nsCompressedCharMap.h" -#include "nsNetUtil.h" -#include "nsClassHashtable.h" -#include "nsAutoBuffer.h" -#include "nsFontConfigUtils.h" - -#include -#include -#include - -#define FORCE_PR_LOG -#include "prlog.h" - -// Abstract class nsFontXft is the base class for nsFontXftUnicode and -// nsFontXftCustom, either of which is an instance of fonts. The -// |nsFontMetricsXft| class is made up of a collection of these little -// fonts, really. - -class nsAutoDrawSpecBuffer; - -class nsFontXft { -public: - nsFontXft(FcPattern *aPattern, FcPattern *aFontName); - virtual ~nsFontXft() = 0; - - // Callers outside of FindFont and DoMatch (which deal directly with - // mLoadedFonts) do not need to call this; they can access mXftFont - // directly since it is guaranteed to be non-null. - XftFont *GetXftFont (void); - virtual nsresult GetTextExtents32 (const FcChar32 *aString, PRUint32 aLen, - XGlyphInfo &aGlyphInfo); - gint GetWidth32 (const FcChar32 *aString, PRUint32 aLen); - -#ifdef MOZ_MATHML - nsresult GetBoundingMetrics32 (const FcChar32 *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics); -#endif /* MOZ_MATHML */ - - PRInt16 GetMaxAscent(void); - PRInt16 GetMaxDescent(void); - - virtual PRBool HasChar(PRUint32 aChar) = 0; - virtual FT_UInt CharToGlyphIndex(FcChar32 aChar); - - virtual nsresult DrawStringSpec(FcChar32* aString, PRUint32 aLen, - void *aData); - - // a reference to the font loaded and information about it. - XftFont *mXftFont; - FcPattern *mPattern; - FcPattern *mFontName; - FcCharSet *mCharset; -}; - -class nsFontXftInfo; - -// class for regular 'Unicode' fonts that are actually what they claim to be. -class nsFontXftUnicode : public nsFontXft { -public: - nsFontXftUnicode(FcPattern *aPattern, FcPattern *aFontName) - : nsFontXft(aPattern, aFontName) - { } - - virtual ~nsFontXftUnicode(); - - virtual PRBool HasChar (PRUint32 aChar); -}; - -// class for custom encoded fonts that pretend to have Unicode cmap. -// There are two kinds of them: -// 1. 'narrow' custom encoded fonts such as mathematica fonts, -// TeX Computer Roman fonts, Symbol font, etc. -// 2. 'wide' custom encoded fonts such as -// Korean Jamo fonts, non-opentype fonts for Indic scripts. -// -// The biggest difference between 'narrow' and 'wide' fonts is that -// the result of calling mConverter for 'wide' fonts is a sequence of -// 16bit pseudo-Unicode code points. For 'narrow' fonts, it's -// a sequence of 8bit code points. -class nsFontXftCustom : public nsFontXft { -public: - nsFontXftCustom(FcPattern* aPattern, - FcPattern* aFontName, - nsFontXftInfo* aFontInfo) - : nsFontXft(aPattern, aFontName) - , mFontInfo(aFontInfo) - , mFT_Face(nsnull) - { } - - virtual ~nsFontXftCustom(); - - virtual PRBool HasChar (PRUint32 aChar); - virtual FT_UInt CharToGlyphIndex (FcChar32 aChar); - virtual nsresult GetTextExtents32 (const FcChar32 *aString, - PRUint32 aLen, XGlyphInfo &aGlyphInfo); - virtual nsresult DrawStringSpec (FcChar32* aString, PRUint32 aLen, - void *aData); - -private: - nsFontXftInfo *mFontInfo; - - // freetype fontface : used for direct access to glyph indices - // in GetWidth32() and DrawStringSpec(). - FT_Face mFT_Face; - nsresult SetFT_FaceCharmap (void); -}; - -enum nsXftFontType { - eFontTypeUnicode, - eFontTypeCustom, - eFontTypeCustomWide -}; - -// a class to hold some essential information about font. -// it's shared and cached with 'family name' as hash key. -class nsFontXftInfo { - public: - nsFontXftInfo() : mCCMap(nsnull), mConverter(0), - mFontType(eFontTypeUnicode) - { } - - ~nsFontXftInfo() { - if (mCCMap) - FreeCCMap(mCCMap); - } - - // Char. coverage map(replacing mCharset in nsFontXft) - PRUint16* mCCMap; - // converter from Unicode to font-specific encoding - nsCOMPtr mConverter; - // Unicode, Custom, CustomWide - nsXftFontType mFontType; - // Truetype cmap to use for direct retrieval of GIDs with FT_Get_Char_Index - // for 'narrow' custom fonts. - FT_Encoding mFT_Encoding; -}; - -struct DrawStringData { - nscoord x; - nscoord y; - const nscoord *spacing; - nscoord xOffset; - nsRenderingContextGTK *context; - XftDraw *draw; - XftColor color; - float p2t; - nsAutoDrawSpecBuffer *drawBuffer; -}; - -#ifdef MOZ_MATHML -struct BoundingMetricsData { - nsBoundingMetrics *bm; - PRBool firstTime; -}; -#endif /* MOZ_MATHML */ - -#define AUTO_BUFFER_SIZE 3000 -typedef nsAutoBuffer nsAutoFcChar32Buffer; - -static int CompareFontNames (const void* aArg1, const void* aArg2, - void* aClosure); -static nsresult EnumFontsXft (nsIAtom* aLangGroup, const char* aGeneric, - PRUint32* aCount, PRUnichar*** aResult); - -static void ConvertCharToUCS4 (const char *aString, - PRUint32 aLength, - nsAutoFcChar32Buffer &aOutBuffer, - PRUint32 *aOutLen); -static void ConvertUnicharToUCS4 (const PRUnichar *aString, - PRUint32 aLength, - nsAutoFcChar32Buffer &aOutBuffer, - PRUint32 *aOutLen); -static nsresult ConvertUCS4ToCustom (FcChar32 *aSrc, PRUint32 aSrcLen, - PRUint32& aDestLen, - nsIUnicodeEncoder *aConverter, - PRBool aIsWide, - nsAutoFcChar32Buffer &Result); - -#ifdef MOZ_WIDGET_GTK2 -static void GdkRegionSetXftClip(GdkRegion *aGdkRegion, XftDraw *aDraw); -#endif - -// This is the scaling factor that we keep fonts limited to against -// the display size. If a pixel size is requested that is more than -// this factor larger than the height of the display, it's clamped to -// that value instead of the requested size. -#define FONT_MAX_FONT_SCALE 2 - -#define UCS2_REPLACEMENT 0xFFFD - -#define IS_NON_BMP(c) ((c) >> 16) -#define IS_NON_SURROGATE(c) ((c < 0xd800 || c > 0xdfff)) - -// a helper class for Xft glyph drawings -class nsAutoDrawSpecBuffer { -public: - enum {BUFFER_LEN=1024}; - nsAutoDrawSpecBuffer(XftDraw *aDraw, XftColor *aColor) : - mDraw(aDraw), mColor(aColor), mSpecPos(0) {} - - ~nsAutoDrawSpecBuffer() { - Flush(); - } - - void Flush(); - void Draw(nscoord x, nscoord y, XftFont *font, FT_UInt glyph); - -private: - XftDraw *mDraw; - XftColor *mColor; - PRUint32 mSpecPos; - XftGlyphFontSpec mSpecBuffer[BUFFER_LEN]; -}; - - -PRLogModuleInfo *gXftFontLoad = nsnull; -static int gNumInstances = 0; - -#undef DEBUG_XFT_MEMORY -#ifdef DEBUG_XFT_MEMORY - -extern "C" { -extern void XftMemReport(void); -extern void FcMemReport(void); -} -#endif - -static nsresult -EnumFontsXft(nsIAtom* aLangGroup, const char* aGeneric, - PRUint32* aCount, PRUnichar*** aResult); - -static NS_DEFINE_CID(kCharsetConverterManagerCID, - NS_ICHARSETCONVERTERMANAGER_CID); - -static PRBool gInitialized = PR_FALSE; -static nsIPersistentProperties* gFontEncodingProperties = nsnull; -static nsICharsetConverterManager* gCharsetManager = nsnull; - -typedef nsClassHashtable nsFontXftInfoHash; -static nsFontXftInfoHash gFontXftMaps; -#define INITIAL_FONT_MAP_SIZE 32 - -static nsresult GetEncoding(const char* aFontName, - char **aEncoding, - nsXftFontType &aType, - FT_Encoding &aFTEncoding); -static nsresult GetConverter(const char* aEncoding, - nsIUnicodeEncoder** aConverter); -static nsresult FreeGlobals(void); -static nsFontXftInfo* GetFontXftInfo(FcPattern* aPattern); - -nsFontMetricsXft::nsFontMetricsXft(): mMiniFont(nsnull) -{ - if (!gXftFontLoad) - gXftFontLoad = PR_NewLogModule("XftFontLoad"); - - ++gNumInstances; -} - -nsFontMetricsXft::~nsFontMetricsXft() -{ - if (mDeviceContext) - mDeviceContext->FontMetricsDeleted(this); - - if (mPattern) - FcPatternDestroy(mPattern); - - for (PRInt32 i= mLoadedFonts.Count() - 1; i >= 0; --i) { - nsFontXft *font = (nsFontXft *)mLoadedFonts.ElementAt(i); - delete font; - } - - if (mMiniFont) - XftFontClose(GDK_DISPLAY(), mMiniFont); - - if (--gNumInstances == 0) { - FreeGlobals(); -#ifdef DEBUG_XFT_MEMORY - XftMemReport(); - FcMemReport(); -#endif - } -} - -NS_IMPL_ISUPPORTS1(nsFontMetricsXft, nsIFontMetrics) - -// nsIFontMetrics impl - -NS_IMETHODIMP -nsFontMetricsXft::Init(const nsFont& aFont, nsIAtom* aLangGroup, - nsIDeviceContext *aContext) -{ - mFont = aFont; - mLangGroup = aLangGroup; - - // Hang onto the device context - mDeviceContext = aContext; - - float app2dev = mDeviceContext->AppUnitsToDevUnits(); - mPixelSize = NSTwipsToFloatPixels(mFont.size, app2dev); - - // 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(); - mPixelSize = PR_MIN(screenPixels * FONT_MAX_FONT_SCALE, mPixelSize); - - // enumerate over the font names passed in - mFont.EnumerateFamilies(nsFontMetricsXft::EnumFontCallback, this); - - nsCOMPtr prefService; - prefService = do_GetService(NS_PREF_CONTRACTID); - if (!prefService) - return NS_ERROR_FAILURE; - - nsXPIDLCString value; - const char* langGroup; - mLangGroup->GetUTF8String(&langGroup); - - // Set up the default font name if it's not set - if (!mGenericFont) { - nsCAutoString name("font.default."); - name.Append(langGroup); - prefService->CopyCharPref(name.get(), getter_Copies(value)); - - if (value.get()) - mDefaultFont = value.get(); - else - mDefaultFont = "serif"; - - mGenericFont = &mDefaultFont; - } - - // set up the minimum sizes for fonts - if (mLangGroup) { - nsCAutoString name("font.min-size."); - - if (mGenericFont->Equals("monospace")) - name.Append("fixed"); - else - name.Append("variable"); - - name.Append(char('.')); - name.Append(langGroup); - - PRInt32 minimum = 0; - nsresult res; - res = prefService->GetIntPref(name.get(), &minimum); - if (NS_FAILED(res)) - prefService->GetDefaultIntPref(name.get(), &minimum); - - if (minimum < 0) - minimum = 0; - - if (mPixelSize < minimum) - mPixelSize = minimum; - } - - // Make sure that the pixel size is at least greater than zero - if (mPixelSize < 1) { -#ifdef DEBUG - printf("*** Warning: nsFontMetricsXft was passed a pixel size of %f\n", - mPixelSize); -#endif - mPixelSize = 1; - } - if (!gInitialized) { - CallGetService(kCharsetConverterManagerCID, &gCharsetManager); - if (!gCharsetManager) { - FreeGlobals(); - return NS_ERROR_FAILURE; - } - - if (!gFontXftMaps.IsInitialized() && - !gFontXftMaps.Init(INITIAL_FONT_MAP_SIZE)) { - FreeGlobals(); - return NS_ERROR_OUT_OF_MEMORY; - } - - gInitialized = PR_TRUE; - } - - if (NS_FAILED(RealizeFont())) - return NS_ERROR_FAILURE; - - return NS_OK; -} - -NS_IMETHODIMP -nsFontMetricsXft::Destroy() -{ - mDeviceContext = nsnull; - - return NS_OK; -} - -NS_IMETHODIMP -nsFontMetricsXft::GetLangGroup(nsIAtom** aLangGroup) -{ - *aLangGroup = mLangGroup; - NS_IF_ADDREF(*aLangGroup); - - return NS_OK; -} - -NS_IMETHODIMP -nsFontMetricsXft::GetFontHandle(nsFontHandle &aHandle) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -// nsIFontMetricsXft impl - -nsresult -nsFontMetricsXft::GetWidth(const char* aString, PRUint32 aLength, - nscoord& aWidth, - nsRenderingContextGTK *aContext) -{ - NS_TIMELINE_MARK_FUNCTION("GetWidth"); - - XftFont *font = mWesternFont->mXftFont; - NS_ASSERTION(font, "FindFont returned a bad font"); - - XGlyphInfo glyphInfo; - - // casting away const for aString but it should be safe - XftTextExtents8(GDK_DISPLAY(), font, (FcChar8 *)aString, - aLength, &glyphInfo); - - float f; - f = mDeviceContext->DevUnitsToAppUnits(); - aWidth = NSToCoordRound(glyphInfo.xOff * f); - - return NS_OK; -} - -nsresult -nsFontMetricsXft::GetWidth(const PRUnichar* aString, PRUint32 aLength, - nscoord& aWidth, PRInt32 *aFontID, - nsRenderingContextGTK *aContext) -{ - NS_TIMELINE_MARK_FUNCTION("GetWidth"); - if (!aLength) { - aWidth = 0; - return NS_OK; - } - - gint rawWidth = RawGetWidth(aString, aLength); - - float f; - f = mDeviceContext->DevUnitsToAppUnits(); - aWidth = NSToCoordRound(rawWidth * f); - - if (aFontID) - *aFontID = 0; - - return NS_OK; -} - -nsresult -nsFontMetricsXft::GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - NS_TIMELINE_MARK_FUNCTION("GetTextDimensions"); - aDimensions.Clear(); - - if (!aLength) - return NS_OK; - - nsresult rv; - rv = EnumerateGlyphs(aString, aLength, - &nsFontMetricsXft::TextDimensionsCallback, - &aDimensions); - - NS_ENSURE_SUCCESS(rv, rv); - - float P2T; - P2T = mDeviceContext->DevUnitsToAppUnits(); - - aDimensions.width = NSToCoordRound(aDimensions.width * P2T); - aDimensions.ascent = NSToCoordRound(aDimensions.ascent * P2T); - aDimensions.descent = NSToCoordRound(aDimensions.descent * P2T); - - if (nsnull != aFontID) - *aFontID = 0; - - return NS_OK; -} - -nsresult -nsFontMetricsXft::GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - NS_NOTREACHED("GetTextDimensions"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -nsFontMetricsXft::GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) -{ - NS_NOTREACHED("GetTextDimensions"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -nsFontMetricsXft::DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface) -{ - NS_TIMELINE_MARK_FUNCTION("DrawString"); - - // The data we will carry through the function - DrawStringData data; - memset(&data, 0, sizeof(data)); - - data.x = aX; - data.y = aY; - data.spacing = aSpacing; - data.context = aContext; - data.p2t = mDeviceContext->DevUnitsToAppUnits(); - - PrepareToDraw(aContext, aSurface, &data.draw, data.color); - - nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color); - data.drawBuffer = &drawBuffer; - - return EnumerateGlyphs(aString, aLength, - &nsFontMetricsXft::DrawStringCallback, &data); -} - -nsresult -nsFontMetricsXft::DrawString(const PRUnichar* aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface) -{ - NS_TIMELINE_MARK_FUNCTION("DrawString"); - - // The data we will carry through the function - DrawStringData data; - memset(&data, 0, sizeof(data)); - - data.x = aX; - data.y = aY; - data.spacing = aSpacing; - data.context = aContext; - data.p2t = mDeviceContext->DevUnitsToAppUnits(); - - // set up our colors and clip regions - PrepareToDraw(aContext, aSurface, &data.draw, data.color); - - nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color); - data.drawBuffer = &drawBuffer; - - return EnumerateGlyphs(aString, aLength, - &nsFontMetricsXft::DrawStringCallback, &data); -} - -#ifdef MOZ_MATHML - -nsresult -nsFontMetricsXft::GetBoundingMetrics(const char *aString, PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - nsRenderingContextGTK *aContext) -{ - aBoundingMetrics.Clear(); - - if (!aString || !aLength) - return NS_ERROR_FAILURE; - - // The data we will carry through the function - BoundingMetricsData data; - data.bm = &aBoundingMetrics; - // the beginning of a string needs a special treatment (see - // 'operator +' definition of nsBoundingMetrics.) - data.firstTime = PR_TRUE; - - nsresult rv; - rv = EnumerateGlyphs(aString, aLength, - &nsFontMetricsXft::BoundingMetricsCallback, &data); - NS_ENSURE_SUCCESS(rv, rv); - - float P2T; - P2T = mDeviceContext->DevUnitsToAppUnits(); - - aBoundingMetrics.leftBearing = - NSToCoordRound(aBoundingMetrics.leftBearing * P2T); - aBoundingMetrics.rightBearing = - NSToCoordRound(aBoundingMetrics.rightBearing * P2T); - aBoundingMetrics.width = NSToCoordRound(aBoundingMetrics.width * P2T); - aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T); - aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T); - - return NS_OK; -} - -nsresult -nsFontMetricsXft::GetBoundingMetrics(const PRUnichar *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - PRInt32 *aFontID, - nsRenderingContextGTK *aContext) -{ - aBoundingMetrics.Clear(); - - if (!aString || !aLength) - return NS_ERROR_FAILURE; - - // The data we will carry through the function - BoundingMetricsData data; - data.bm = &aBoundingMetrics; - // the beginning of a string needs a special treatment (see - // 'operator +' definition of nsBoundingMetrics.) - data.firstTime = PR_TRUE; - - nsresult rv; - rv = EnumerateGlyphs(aString, aLength, - &nsFontMetricsXft::BoundingMetricsCallback, &data); - NS_ENSURE_SUCCESS(rv, rv); - - float P2T; - P2T = mDeviceContext->DevUnitsToAppUnits(); - - aBoundingMetrics.leftBearing = - NSToCoordRound(aBoundingMetrics.leftBearing * P2T); - aBoundingMetrics.rightBearing = - NSToCoordRound(aBoundingMetrics.rightBearing * P2T); - aBoundingMetrics.width = NSToCoordRound(aBoundingMetrics.width * P2T); - aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T); - aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T); - - if (nsnull != aFontID) - *aFontID = 0; - - return NS_OK; -} - -#endif /* MOZ_MATHML */ - -GdkFont* -nsFontMetricsXft::GetCurrentGDKFont(void) -{ - return nsnull; -} - -nsresult -nsFontMetricsXft::SetRightToLeftText(PRBool aIsRTL) -{ - return NS_OK; -} - -PRBool -nsFontMetricsXft::GetRightToLeftText() -{ - return PR_FALSE; -} - -nsresult -nsFontMetricsXft::GetClusterInfo(const PRUnichar *aText, - PRUint32 aLength, - PRUint8 *aClusterStarts) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -PRInt32 -nsFontMetricsXft::GetPosition(const PRUnichar *aText, - PRUint32 aLength, - nsPoint aPt) -{ - return -1; -} - -nsresult -nsFontMetricsXft::GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult -nsFontMetricsXft::GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -PRUint32 -nsFontMetricsXft::GetHints(void) -{ - return 0; -} - -nsresult -nsFontMetricsXft::RealizeFont(void) -{ - // make sure that the western font is loaded since we need that to - // get the font metrics - mWesternFont = FindFont('a'); - if (!mWesternFont) - return NS_ERROR_FAILURE; - - return CacheFontMetrics(); -} - -// rounding and truncation functions for a Freetype floating point number -// (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer -// part and low 6 bits for the fractional part. -#define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1 -#define MOZ_FT_TRUNC(x) ((x) >> 6) -#define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \ - MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s)))) - -nsresult -nsFontMetricsXft::CacheFontMetrics(void) -{ - // Get our scale factor - float f; - float val; - f = mDeviceContext->DevUnitsToAppUnits(); - - // Get our font face - XftFont *xftFont = mWesternFont->mXftFont; - NS_ASSERTION(xftFont, "FindFont returned a bad font"); - - FT_Face face = XftLockFace(xftFont); - if (!face) - return NS_ERROR_NOT_AVAILABLE; - - // mEmHeight (size in pixels of EM height) - int size; - if (FcPatternGetInteger(mWesternFont->mPattern, FC_PIXEL_SIZE, 0, &size) != - FcResultMatch) { - size = 12; - } - mEmHeight = PR_MAX(1, nscoord(size * f)); - - // mMaxAscent - mMaxAscent = nscoord(xftFont->ascent * f); - - // mMaxDescent - mMaxDescent = nscoord(xftFont->descent * f); - - nscoord lineHeight = mMaxAscent + mMaxDescent; - - // mLeading (needs ascent and descent and EM height) - if (lineHeight > mEmHeight) - mLeading = lineHeight - mEmHeight; - else - mLeading = 0; - - // mMaxHeight (needs ascent and descent) - mMaxHeight = lineHeight; - - // mEmAscent (needs maxascent, EM height, ascent and descent) - mEmAscent = nscoord(mMaxAscent * mEmHeight / lineHeight); - - // mEmDescent (needs EM height and EM ascent - mEmDescent = mEmHeight - mEmAscent; - - // mMaxAdvance - mMaxAdvance = nscoord(xftFont->max_advance_width * f); - // X may screw up if we try to measure/draw more than 32767 pixels in - // one operation. - mMaxStringLength = (PRInt32)floor(32767.0/xftFont->max_advance_width); - mMaxStringLength = PR_MAX(1, mMaxStringLength); - - // mSpaceWidth (width of a space) - gint rawWidth; - PRUnichar unispace(' '); - rawWidth = RawGetWidth(&unispace, 1); - mSpaceWidth = NSToCoordRound(rawWidth * f); - - // mAveCharWidth (width of an 'average' char) - PRUnichar xUnichar('x'); - rawWidth = RawGetWidth(&xUnichar, 1); - mAveCharWidth = NSToCoordRound(rawWidth * f); - - // mXHeight (height of an 'x' character) - if (FcCharSetHasChar(mWesternFont->mCharset, xUnichar)) { - XGlyphInfo extents; - XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents); - mXHeight = extents.height; - } - else { - // 56% of ascent, best guess for non-true type or asian fonts - mXHeight = nscoord(((float)mMaxAscent) * 0.56); - } - mXHeight = nscoord(mXHeight * f); - - // mUnderlineOffset (offset for underlines) - val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position, - face->size->metrics.y_scale); - if (val) { - mUnderlineOffset = NSToIntRound(val * f); - } - else { - mUnderlineOffset = - -NSToIntRound(PR_MAX(1, floor(0.1 * xftFont->height + 0.5)) * f); - } - - // mUnderlineSize (thickness of an underline) - val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness, - face->size->metrics.y_scale); - if (val) { - mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(val * f))); - } - else { - mUnderlineSize = - NSToIntRound(PR_MAX(1, floor(0.05 * xftFont->height + 0.5)) * f); - } - - TT_OS2 *os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2); - - // mSuperscriptOffset - if (os2 && os2->ySuperscriptYOffset) { - val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset, - face->size->metrics.y_scale); - mSuperscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f))); - } - else { - mSuperscriptOffset = mXHeight; - } - - // mSubscriptOffset - if (os2 && os2->ySubscriptYOffset) { - val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySubscriptYOffset, - face->size->metrics.y_scale); - // some fonts have the incorrect sign. - val = (val < 0) ? -val : val; - mSubscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f))); - } - else { - mSubscriptOffset = mXHeight; - } - - // mStrikeoutOffset - mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0); - - // mStrikeoutSize - mStrikeoutSize = mUnderlineSize; - - XftUnlockFace(xftFont); - - return NS_OK; -} - -nsFontXft * -nsFontMetricsXft::FindFont(PRUint32 aChar) -{ - - // If mPattern is null, set up the base bits of it so we can - // match. If we need to match later we don't have to set it up - // again. - if (!mPattern) { - SetupFCPattern(); - // did we fail to set it up? - if (!mPattern) - return nsnull; - } - - // go forth and find us some fonts - if (mMatchType == eNoMatch) { - // Optimistically just look for the best match font. - // This can be completed in linear time, which is ideal if all - // of the characters we're asked for can be found in this font. - DoMatch(PR_FALSE); - } - - // Now that we have the fonts loaded and ready to run, return the - // font in our loaded list that supports the character - - if (mLoadedFonts.Count() == 0) { - // No fonts were matched at all. This probably means out-of-memory - // or some equally bad condition. - return nsnull; - } - - PRBool removeFirstFont = PR_FALSE; - nsFontXft *font = (nsFontXft *)mLoadedFonts.ElementAt(0); - if (font->HasChar(aChar)) { - if (font->GetXftFont()) - return font; - removeFirstFont = PR_TRUE; - } - - // We failed to find the character in the best-match font, so load - // _all_ matching fonts if we haven't already done so. - - if (mMatchType == eBestMatch) - DoMatch(PR_TRUE); - - PRInt32 i = 1; - if (removeFirstFont) { - // The first font was bad, so remove it (see below). But do this - // after |DoMatch| since otherwise it will get re-added. - mLoadedFonts.RemoveElementAt(0); - i = 0; - } - - // Now check the remaining fonts - for (; i < mLoadedFonts.Count(); ++i) { - nsFontXft *font = (nsFontXft *)mLoadedFonts.ElementAt(i); - if (font->HasChar(aChar)) { - if (font->GetXftFont()) - return font; - // This is a bad font, so remove it from mLoadedFonts. This - // could happen if it's in fc.cache-1 but the font doesn't exist - // (https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=111973) - // or isn't readable. - mLoadedFonts.RemoveElementAt(i--); - } - } - - // If we got this far, none of the fonts support this character. - // Return nothing. - return nsnull; -} - -void -nsFontMetricsXft::SetupFCPattern(void) -{ - if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) { - printf("[%p] setting up pattern with the following specification:\n", - (void *)this); - - // non-generic families - if (mFontList.Count() && !mFontIsGeneric[0]) { - printf("\tadding non-generic families: "); - for (int i=0; i < mFontList.Count(); ++i) { - if (mFontIsGeneric[i]) - break; - - nsCString *familyName = mFontList.CStringAt(i); - printf("%s, ", familyName->get()); - } - printf("\n"); - } - - // language group - const char *name; - mLangGroup->GetUTF8String(&name); - printf("\tlang group: %s\n", name); - - - } - - mPattern = FcPatternCreate(); - if (!mPattern) - return; - - if (gdk_rgb_get_cmap() != gdk_colormap_get_system()) - XftPatternAddBool(mPattern, XFT_RENDER, False); - - // XXX need to add user defined family - - // Add CSS names - walk the list of fonts, adding the generic as - // the last font - for (int i=0; i < mFontList.Count(); ++i) { - // if this was a generic name, break out of the loop since we - // don't want to add it to the pattern yet - if (mFontIsGeneric[i]) - break;; - - nsCString *familyName = mFontList.CStringAt(i); - NS_AddFFRE(mPattern, familyName, PR_FALSE); - } - - // Add the language group. Note that we do this before adding any - // generics. That's because the language is more important than - // any generic font. - NS_AddLangGroup (mPattern, mLangGroup); - - // If there's a generic add a pref for the generic if there's one - // set. - if (mGenericFont && !mFont.systemFont) { - NS_AddGenericFontFromPref(mGenericFont, mLangGroup, mPattern, - gXftFontLoad); - } - - // Add the generic if there is one. - if (mGenericFont && !mFont.systemFont) - NS_AddFFRE(mPattern, mGenericFont, PR_FALSE); - - if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) { - // generic font - if (mGenericFont && !mFont.systemFont) { - printf("\tadding generic family: %s\n", mGenericFont->get()); - } - - // pixel size - printf("\tpixel,twip size: %f,%d\n", mPixelSize, mFont.size); - - // slant type - printf("\tslant: "); - switch(mFont.style) { - case NS_FONT_STYLE_ITALIC: - printf("italic\n"); - break; - case NS_FONT_STYLE_OBLIQUE: - printf("oblique\n"); - break; - default: - printf("roman\n"); - break; - } - - // weight - printf("\tweight: (orig,calc) %d,%d\n", - mFont.weight, NS_CalculateWeight(mFont.weight)); - - } - - // add the point size - // We've done some round-tripping of floating point numbers so they - // might not be quite right. Since Xft rounds down, add a little, - // so we don't go from 9.00000 to 8.99999 to 8. - FcPatternAddDouble(mPattern, FC_PIXEL_SIZE, mPixelSize + 0.000001); - - // Add the slant type - FcPatternAddInteger(mPattern, FC_SLANT, - NS_CalculateSlant(mFont.style)); - - // Add the weight - FcPatternAddInteger(mPattern, FC_WEIGHT, - NS_CalculateWeight(mFont.weight)); - - // Set up the default substitutions for this font - FcConfigSubstitute(0, mPattern, FcMatchPattern); - XftDefaultSubstitute(GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), - mPattern); -} - -void -nsFontMetricsXft::DoMatch(PRBool aMatchAll) -{ - FcFontSet *set = nsnull; - // now that we have a pattern we can match - FcResult result; - - if (aMatchAll) { - set = FcFontSort(0, mPattern, FcTrue, NULL, &result); - if (!set || set->nfont == 1) { - // There is a bug in older fontconfig versions that causes it to - // bail if it hits a font it can't deal with. - // If this has happened, try just the generic font-family by - // removing everything else from the font list and rebuilding - // the pattern. - - NS_WARNING("Detected buggy fontconfig, falling back to generic font"); - - nsCAutoString genericFont; - if (mGenericFont) - genericFont.Assign(*mGenericFont); - - mFontList.Clear(); - mFontIsGeneric.Clear(); - - mFontList.AppendCString(genericFont); - mFontIsGeneric.AppendElement((void*) PR_TRUE); - mGenericFont = mFontList.CStringAt(0); - - FcPatternDestroy(mPattern); - SetupFCPattern(); - - if (set) - FcFontSetDestroy(set); - - set = FcFontSort(0, mPattern, FcTrue, NULL, &result); - } - } - else { - FcPattern* font = FcFontMatch(0, mPattern, &result); - if (font) { - set = FcFontSetCreate(); - FcFontSetAdd(set, font); - } - } - - // did we not match anything? - if (!set) { - goto loser; - } - - if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) { - printf("matched the following (%d) fonts:\n", set->nfont); - } - - // Create a list of new font objects based on the fonts returned - // as part of the query. We start at mLoadedFonts.Count() so as to - // not re-add the best match font we've already loaded. - for (int i=mLoadedFonts.Count(); i < set->nfont; ++i) { - if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) { - char *name; - FcPatternGetString(set->fonts[i], FC_FAMILY, 0, (FcChar8 **)&name); - printf("\t%s\n", name); - } - - nsFontXft *font; - nsFontXftInfo *info; - nsCOMPtr converter = 0; - - info = GetFontXftInfo(set->fonts[i]); - if (info) { - if (info->mFontType == eFontTypeUnicode) - font = new nsFontXftUnicode(mPattern, set->fonts[i]); - else - font = new nsFontXftCustom(mPattern, set->fonts[i], info); - } - else { // if null is returned, treat it as Unicode font. - font = new nsFontXftUnicode(mPattern, set->fonts[i]); - } - - if (!font) - goto loser; - - // append this font to our list of loaded fonts - mLoadedFonts.AppendElement((void *)font); - } - - // we're done with the set now - FcFontSetDestroy(set); - set = nsnull; - - // Done matching! - if (aMatchAll) - mMatchType = eAllMatching; - else - mMatchType = eBestMatch; - return; - - // if we got this far, something went terribly wrong - loser: - NS_WARNING("nsFontMetricsXft::DoMatch failed to match anything"); - - if (set) - FcFontSetDestroy(set); - - for (PRInt32 i = mLoadedFonts.Count() - 1; i >= 0; --i) { - nsFontXft *font = (nsFontXft *)mLoadedFonts.ElementAt(i); - mLoadedFonts.RemoveElementAt(i); - delete font; - } -} - -gint -nsFontMetricsXft::RawGetWidth(const PRUnichar* aString, PRUint32 aLength) -{ - nscoord width = 0; - nsresult rv; - - rv = EnumerateGlyphs(aString, aLength, - &nsFontMetricsXft::GetWidthCallback, &width); - - if (NS_FAILED(rv)) - width = 0; - - return width; -} - -nsresult -nsFontMetricsXft::SetupMiniFont(void) -{ - // The minifont is initialized lazily. - if (mMiniFont) - return NS_OK; - - FcPattern *pattern = nsnull; - XftFont *font = nsnull; - XftFont *xftFont = mWesternFont->mXftFont; - NS_ASSERTION(xftFont, "FindFont returned a bad font"); - - mMiniFontAscent = xftFont->ascent; - mMiniFontDescent = xftFont->descent; - - pattern = FcPatternCreate(); - if (!pattern) - return NS_ERROR_FAILURE; - - if (gdk_rgb_get_cmap() != gdk_colormap_get_system()) - XftPatternAddBool(mPattern, XFT_RENDER, False); - - FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)"monospace"); - - FcPatternAddInteger(pattern, FC_PIXEL_SIZE, int(0.5 * mPixelSize)); - - FcPatternAddInteger(pattern, FC_WEIGHT, - NS_CalculateWeight(mFont.weight)); - - FcConfigSubstitute(0, pattern, FcMatchPattern); - XftDefaultSubstitute(GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), - pattern); - - FcResult res; - - FcPattern *pat = FcFontMatch(0, pattern, &res); - - if (pat) { - font = XftFontOpenPattern(GDK_DISPLAY(), pat); - - if (font) { - mMiniFont = font; - pat = nsnull; // the font owns the pattern now - } - else { - font = xftFont; - } - } - - // now that the font has been loaded, measure the fonts to find - // the bounds - for (int i=0; i < 16; ++i) { - // create a little mini-string that contains what we want to - // measure. - char c = i < 10 ? '0' + i : 'A' + i - 10; - char str[2]; - str[0] = c; - str[1] = '\0'; - - XGlyphInfo extents; - XftTextExtents8(GDK_DISPLAY(), font, - (FcChar8 *)str, 1, &extents); - - mMiniFontWidth = PR_MAX (mMiniFontWidth, extents.width); - mMiniFontHeight = PR_MAX (mMiniFontHeight, extents.height); - } - - if (!mMiniFont) { - mMiniFontWidth /= 2; - mMiniFontHeight /= 2; - } - - mMiniFontPadding = PR_MAX(mMiniFontHeight / 10, 1); - mMiniFontYOffset = ((mMiniFontAscent + mMiniFontDescent) - - (mMiniFontHeight * 2 + mMiniFontPadding * 5)) / 2; - - - if (pat) - FcPatternDestroy(pat); - if (pattern) - FcPatternDestroy(pattern); - - return NS_OK; -} - -nsresult -nsFontMetricsXft::DrawUnknownGlyph(FcChar32 aChar, - nscoord aX, - nscoord aY, - XftColor *aColor, - XftDraw *aDraw) -{ - int width,height; - int ndigit = (IS_NON_BMP(aChar)) ? 3 : 2; - - // ndigit characters + padding around the fonts. From left to - // right it would be one padding for the glyph box, one for the - // padding in between the box and the left most digit, ndigit - // padding following each of ndigit letters and one for the - // rightmost part of the box. This pattern is used throughout the - // rest of this function. - width = mMiniFontWidth * ndigit + mMiniFontPadding * (ndigit + 3); - height = mMiniFontHeight * 2 + mMiniFontPadding * 5; - - // Draw an outline of a box. We do with this with four calls - // since with one call it would fill in the box. - - // horizontal lines - XftDrawRect(aDraw, aColor, - aX, aY - height, - width, mMiniFontPadding); - XftDrawRect(aDraw, aColor, - aX, aY - mMiniFontPadding, - width, mMiniFontPadding); - - // vertical lines - XftDrawRect(aDraw, aColor, - aX, - aY - height + mMiniFontPadding, - mMiniFontPadding, height - mMiniFontPadding * 2); - XftDrawRect(aDraw, aColor, - aX + width - mMiniFontPadding, - aY - height + mMiniFontPadding, - mMiniFontPadding, height - mMiniFontPadding * 2); - - // If for some reason the mini font couldn't be loaded, just - // return - the box is enough. - if (!mMiniFont) - return NS_OK; - - // now draw the characters - char buf[7]; - PR_snprintf (buf, sizeof(buf), "%0*X", ndigit * 2, aChar); - - // Draw the 'ndigit * 2' characters - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontPadding * 2, - aY - mMiniFontHeight - mMiniFontPadding * 3, - (FcChar8 *)&buf[0], 1); - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontWidth + mMiniFontPadding * 3, - aY - mMiniFontHeight - mMiniFontPadding * 3, - (FcChar8 *)&buf[1], 1); - - if (ndigit == 2) { - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontPadding * 2, - aY - mMiniFontPadding * 2, - (FcChar8 *)&buf[2], 1); - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontWidth + mMiniFontPadding * 3, - aY - mMiniFontPadding * 2, - (FcChar8 *)&buf[3], 1); - - return NS_OK; - } - - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontWidth * 2 + mMiniFontPadding * 4, - aY - mMiniFontHeight - mMiniFontPadding * 3, - (FcChar8 *)&buf[2], 1); - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontPadding * 2, - aY - mMiniFontPadding * 2, - (FcChar8 *)&buf[3], 1); - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontWidth + mMiniFontPadding * 3, - aY - mMiniFontPadding * 2, - (FcChar8 *)&buf[4], 1); - XftDrawString8(aDraw, aColor, mMiniFont, - aX + mMiniFontWidth * 2 + mMiniFontPadding * 4, - aY - mMiniFontPadding * 2, - (FcChar8 *)&buf[5], 1); - - return NS_OK; -} - -nsresult -nsFontMetricsXft::EnumerateXftGlyphs(const FcChar32 *aString, PRUint32 aLen, - GlyphEnumeratorCallback aCallback, - void *aCallbackData) -{ - nsFontXft* prevFont = nsnull; - PRUint32 start = 0; - nsresult rv = NS_OK; - PRUint32 i = 0; - - for ( ; i < aLen; i ++) { - nsFontXft *currFont = FindFont(aString[i]); - - // Don't try to handle more than 512 characters at once, since - // Xft text measurement can't deal with anything with a width of - // more than 2^15 (32768) pixels. This is a hack, and it could - // break things like combining characters, but that's not nearly - // as bad as not displaying anything, and it's also very rare to - // draw strings this long without any breaks. - if (currFont != prevFont || i - start > 512) { - if (i > start) { - rv = (this->*aCallback)(&aString[start], i - start, prevFont, - aCallbackData); - NS_ENSURE_SUCCESS(rv, rv); - } - prevFont = currFont; - start = i; - } - } - - if (i > start) - rv = (this->*aCallback)(&aString[start], i - start, prevFont, - aCallbackData); - - return rv; -} - -nsresult -nsFontMetricsXft::EnumerateGlyphs(const PRUnichar *aString, - PRUint32 aLen, - GlyphEnumeratorCallback aCallback, - void *aCallbackData) -{ - PRUint32 len; - nsAutoFcChar32Buffer charBuffer; - - NS_ENSURE_TRUE(aLen, NS_OK); - - ConvertUnicharToUCS4(aString, aLen, charBuffer, &len); - if (!len) - return NS_ERROR_OUT_OF_MEMORY; - - return EnumerateXftGlyphs(charBuffer.get(), len, aCallback, aCallbackData); -} - -nsresult -nsFontMetricsXft::EnumerateGlyphs(const char *aString, - PRUint32 aLen, - GlyphEnumeratorCallback aCallback, - void *aCallbackData) -{ - PRUint32 len; - nsAutoFcChar32Buffer charBuffer; - - NS_ENSURE_TRUE(aLen, NS_OK); - - // Convert the incoming string into an array of UCS4 chars - ConvertCharToUCS4(aString, aLen, charBuffer, &len); - if (!len) - return NS_ERROR_OUT_OF_MEMORY; - - return EnumerateXftGlyphs(charBuffer.get(), len, aCallback, aCallbackData); -} - -void -nsFontMetricsXft::PrepareToDraw(nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface, - XftDraw **aDraw, XftColor &aColor) -{ - // Set our color - nscolor rccolor; - - aContext->GetColor(rccolor); - - aColor.pixel = gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(rccolor)); - aColor.color.red = (NS_GET_R(rccolor) << 8) | NS_GET_R(rccolor); - aColor.color.green = (NS_GET_G(rccolor) << 8) | NS_GET_G(rccolor); - aColor.color.blue = (NS_GET_B(rccolor) << 8) | NS_GET_B(rccolor); - aColor.color.alpha = 0xffff; - - *aDraw = aSurface->GetXftDraw(); - - nsCOMPtr lastRegion; - nsCOMPtr clipRegion; - - aSurface->GetLastXftClip(getter_AddRefs(lastRegion)); - aContext->GetClipRegion(getter_AddRefs(clipRegion)); - - // avoid setting the clip, if possible - if (!lastRegion || !clipRegion || !lastRegion->IsEqual(*clipRegion)) { - aSurface->SetLastXftClip(clipRegion); - - GdkRegion *rgn = nsnull; - clipRegion->GetNativeRegion((void *&)rgn); - -#ifdef MOZ_WIDGET_GTK2 - GdkRegionSetXftClip(rgn, *aDraw); -#endif - } -} - -nsresult -nsFontMetricsXft::DrawStringCallback(const FcChar32 *aString, PRUint32 aLen, - nsFontXft *aFont, void *aData) -{ - DrawStringData *data = (DrawStringData *)aData; - - // If there was no font found for this character, just draw the - // unknown glyph character - if (!aFont) { - SetupMiniFont(); - - for (PRUint32 i = 0; ix + data->xOffset; - nscoord y = data->y; - - // convert this into device coordinates - data->context->GetTranMatrix()->TransformCoord(&x, &y); - - DrawUnknownGlyph(ch, x, y + mMiniFontYOffset, &data->color, - data->draw); - - if (data->spacing) { - data->xOffset += *data->spacing; - data->spacing += IS_NON_BMP(ch) ? 2 : 1; - } - else { - data->xOffset += - NSToCoordRound((mMiniFontWidth*(IS_NON_BMP(ch) ? 3 : 2) + - mMiniFontPadding*(IS_NON_BMP(ch) ? 6:5)) * - data->p2t); - } - } - - // We're done. - return NS_OK; - } - - // actually process the specbuffer converting the input string - // to custom font code if necessary. - return aFont->DrawStringSpec(NS_CONST_CAST(FcChar32 *, aString), - aLen, data); -} - -nsresult -nsFontMetricsXft::TextDimensionsCallback(const FcChar32 *aString, PRUint32 aLen, - nsFontXft *aFont, void *aData) -{ - nsTextDimensions *dimensions = (nsTextDimensions *)aData; - - if (!aFont) { - SetupMiniFont(); - for (PRUint32 i = 0; iwidth += - mMiniFontWidth * (IS_NON_BMP(aString[i]) ? 3 : 2) + - mMiniFontPadding * (IS_NON_BMP(aString[i]) ? 6 : 5); - } - - if (dimensions->ascent < mMiniFontAscent) - dimensions->ascent = mMiniFontAscent; - if (dimensions->descent < mMiniFontDescent) - dimensions->descent = mMiniFontDescent; - - return NS_OK; - } - - // get the metric after converting the input string to - // custom font code if necessary. - XGlyphInfo glyphInfo; - nsresult rv = aFont->GetTextExtents32(aString, aLen, glyphInfo); - NS_ENSURE_SUCCESS(rv, rv); - - dimensions->width += glyphInfo.xOff; - - nscoord tmpMaxAscent = aFont->GetMaxAscent(); - nscoord tmpMaxDescent = aFont->GetMaxDescent(); - - if (dimensions->ascent < tmpMaxAscent) - dimensions->ascent = tmpMaxAscent; - if (dimensions->descent < tmpMaxDescent) - dimensions->descent = tmpMaxDescent; - - return NS_OK; -} - -nsresult -nsFontMetricsXft::GetWidthCallback(const FcChar32 *aString, PRUint32 aLen, - nsFontXft *aFont, void *aData) -{ - nscoord *width = (nscoord*)aData; - - if (!aFont) { - SetupMiniFont(); - for (PRUint32 i = 0; i < aLen; i++) { - *width += mMiniFontWidth * (IS_NON_BMP(aString[i]) ? 3 : 2) + - mMiniFontPadding * (IS_NON_BMP(aString[i]) ? 6 : 5); - } - return NS_OK; - } - - *width += aFont->GetWidth32(aString, aLen); - return NS_OK; -} - -#ifdef MOZ_MATHML -nsresult -nsFontMetricsXft::BoundingMetricsCallback(const FcChar32 *aString, - PRUint32 aLen, nsFontXft *aFont, - void *aData) -{ - BoundingMetricsData *data = (BoundingMetricsData *)aData; - nsBoundingMetrics bm; - - if (!aFont) { - SetupMiniFont(); - - // Note: All fields of bm initialized to 0 in its constructor. - for (PRUint32 i = 0; i < aLen; i++) { - bm.width += mMiniFontWidth * (IS_NON_BMP(aString[i]) ? 3 : 2) + - mMiniFontPadding * (IS_NON_BMP(aString[i]) ? 6 : 5); - bm.rightBearing += bm.width; // no need to set leftBearing. - } - bm.ascent = mMiniFontAscent; - bm.descent = mMiniFontDescent; - } - else { - nsresult rv; - rv = aFont->GetBoundingMetrics32(aString, aLen, bm); - NS_ENSURE_SUCCESS(rv, rv); - } - - if (data->firstTime) { - *(data->bm) = bm; - data->firstTime = PR_FALSE; - } - else { - *(data->bm) += bm; - } - - return NS_OK; -} -#endif /* MOZ_MATHML */ - -/* static */ -nsresult -nsFontMetricsXft::FamilyExists(nsIDeviceContext *aDevice, - const nsString &aName) -{ - // fontconfig family name is always in UTF-8 - NS_ConvertUTF16toUTF8 name(aName); - - FcFontSet *set = nsnull; - FcObjectSet *os = nsnull; - - FcPattern *pat = FcPatternCreate(); - if (!pat) - return NS_ERROR_FAILURE; - - nsresult rv = NS_ERROR_FAILURE; - - // Build a list of familes and walk the list looking to see if we - // have it. - os = FcObjectSetBuild(FC_FAMILY, NULL); - if (!os) - goto end; - - set = FcFontList(0, pat, os); - - if (!set || !set->nfont) - goto end; - - for (int i = 0; i < set->nfont; ++i) { - const char *tmpname = NULL; - if (FcPatternGetString(set->fonts[i], FC_FAMILY, 0, - (FcChar8 **)&tmpname) != FcResultMatch) { - continue; - } - - // do they match? - if (!Compare(nsDependentCString(tmpname), name, - nsCaseInsensitiveCStringComparator())) { - rv = NS_OK; - break; - } - } - - end: - if (set) - FcFontSetDestroy(set); - if (os) - FcObjectSetDestroy(os); - - FcPatternDestroy(pat); - - return rv; -} - -/* static */ -PRBool -nsFontMetricsXft::EnumFontCallback(const nsString &aFamily, PRBool aIsGeneric, - void *aData) -{ - NS_ConvertUTF16toUTF8 name(aFamily); - - // The newest fontconfig does the full Unicode case folding so that - // we're being lazy here by calling |ToLowerCase| after converting - // to UTF-8 assuming that in virtually all cases, we just have to - // fold [A-Z]. (bug 223653). - ToLowerCase(name); - nsFontMetricsXft *metrics = (nsFontMetricsXft *)aData; - metrics->mFontList.AppendCString(name); - metrics->mFontIsGeneric.AppendElement((void *)aIsGeneric); - if (aIsGeneric) { - metrics->mGenericFont = - metrics->mFontList.CStringAt(metrics->mFontList.Count() - 1); - return PR_FALSE; // stop processing - } - - return PR_TRUE; // keep processing -} - -// nsFontEnumeratorXft class - -nsFontEnumeratorXft::nsFontEnumeratorXft() -{ -} - -NS_IMPL_ISUPPORTS1(nsFontEnumeratorXft, nsIFontEnumerator) - -NS_IMETHODIMP -nsFontEnumeratorXft::EnumerateAllFonts(PRUint32 *aCount, PRUnichar ***aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - NS_ENSURE_ARG_POINTER(aCount); - *aCount = 0; - - return EnumFontsXft(nsnull, nsnull, aCount, aResult); -} - -NS_IMETHODIMP -nsFontEnumeratorXft::EnumerateFonts(const char *aLangGroup, - const char *aGeneric, - PRUint32 *aCount, PRUnichar ***aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - NS_ENSURE_ARG_POINTER(aCount); - *aCount = 0; - - // aLangGroup=null or "" means any (i.e., don't care) - // aGeneric=null or "" means any (i.e, don't care) - nsCOMPtr langGroup; - if (aLangGroup && *aLangGroup) - langGroup = do_GetAtom(aLangGroup); - const char* generic = nsnull; - if (aGeneric && *aGeneric) - generic = aGeneric; - - return EnumFontsXft(langGroup, generic, aCount, aResult); -} - -NS_IMETHODIMP -nsFontEnumeratorXft::HaveFontFor(const char *aLangGroup, PRBool *aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = PR_FALSE; - NS_ENSURE_ARG_POINTER(aLangGroup); - - *aResult = PR_TRUE; // always return true for now. - // Finish me - ftang - return NS_OK; -} - -NS_IMETHODIMP -nsFontEnumeratorXft::GetDefaultFont(const char *aLangGroup, - const char *aGeneric, PRUnichar **aResult) -{ - // aLangGroup=null or "" means any (i.e., don't care) - // aGeneric=null or "" means any (i.e, don't care) - - NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - -#if 0 - //XXX Some voodoo inspired from the thread: - //XXX http://www.mail-archive.com/fonts@xfree86.org/msg01344.html - //XXX please iterate to turn this on when you are happy/ready - - FcResult res; - FcPattern* match_pattern = NULL; - if (aGeneric && *aGeneric) - match_pattern = FcNameParse(aGeneric); - else - match_pattern = FcPatternCreate(); - - if (!match_pattern) - return NS_OK; // not fatal, just return an empty default name - - if (aLangGroup && *aLangGroup) { - nsCOMPtr langGroup = do_GetAtom(aLangGroup); - NS_AddLangGroup(match_pattern, langGroup); - } - - FcConfigSubstitute(0, match_pattern, FcMatchPattern); - FcDefaultSubstitute(match_pattern); - FcPattern* result_pattern = FcFontMatch(0, match_pattern, &res); - if (result_pattern) { - char *family; - FcPatternGetString(result_pattern, FC_FAMILY, 0, (FcChar8 **)&family); - PRUnichar* name = NS_STATIC_CAST(PRUnichar *, - nsMemory::Alloc ((strlen (family) + 1) - * sizeof (PRUnichar))); - if (name) { - PRUnichar *r = name; - for (char *f = family; *f; ++f) - *r++ = *f; - *r = '\0'; - - *aResult = name; - } - - FcPatternDestroy(result_pattern); - } - FcPatternDestroy(match_pattern); -#endif - - return NS_OK; -} - -NS_IMETHODIMP -nsFontEnumeratorXft::UpdateFontList(PRBool *_retval) -{ - *_retval = PR_FALSE; // always return false for now - return NS_OK; -} - -// class nsFontXft - -nsFontXft::nsFontXft(FcPattern *aPattern, FcPattern *aFontName) -{ - // save our pattern - we own it now - mPattern = aPattern; - mFontName = aFontName; - // don't destroy it out from under us - FcPatternReference(aPattern); - FcPatternReference(mFontName); - - mXftFont = nsnull; - - // set up our charset - mCharset = nsnull; - FcCharSet *charset = nsnull; - - // this references an internal charset, we need to copy it - FcPatternGetCharSet(aFontName, FC_CHARSET, 0, &charset); - if (charset) - mCharset = FcCharSetCopy(charset); -} - -nsFontXft::~nsFontXft() -{ - if (mXftFont) - XftFontClose(GDK_DISPLAY(), mXftFont); - if (mCharset) - FcCharSetDestroy(mCharset); - if (mPattern) - FcPatternDestroy(mPattern); - if (mFontName) - FcPatternDestroy(mFontName); -} - -XftFont * -nsFontXft::GetXftFont(void) -{ - if (!mXftFont) { - FcPattern *pat = FcFontRenderPrepare(0, mPattern, mFontName); - if (!pat) - return nsnull; - - // bug 196312 : work around problem with CJK bi-width fonts - // and fontconfig prior to 2.2. CJK bi-width fonts are regarded - // as genuinely monospace by fontconfig that sets FC_SPACING - // to FC_MONOSPACE, which makes Xft drawing/measuring routines - // use the global advance width (the width of double width glyphs - // and twice the width of single width glyphs) even for single width - // characters (e.g. Latin letters and digits). This results in - // spaced-out ('s p a c e d - o u t') rendering. By deleting - // FC_SPACING here, we're emulating the behavior of fontconfig 2.2 or - // later that does not set FC_SPACING for any font. - if (FcGetVersion() < 20300) - FcPatternDel(pat, FC_SPACING); - - mXftFont = XftFontOpenPattern(GDK_DISPLAY(), pat); - if (!mXftFont) - FcPatternDestroy(pat); - } - - return mXftFont; -} - -// used by GetWidth32, GetBoundingMetrics32, and TextDimensionCallback -nsresult -nsFontXft::GetTextExtents32(const FcChar32 *aString, PRUint32 aLen, - XGlyphInfo &aGlyphInfo) -{ - NS_PRECONDITION(mXftFont, "FindFont should not return bad fonts"); - - // NS_CONST_CAST needed for older versions of Xft - XftTextExtents32(GDK_DISPLAY(), mXftFont, - NS_CONST_CAST(FcChar32*, aString), aLen, &aGlyphInfo); - - return NS_OK; -} - -gint -nsFontXft::GetWidth32(const FcChar32 *aString, PRUint32 aLen) -{ - XGlyphInfo glyphInfo; - GetTextExtents32(aString, aLen, glyphInfo); - - return glyphInfo.xOff; -} - -#ifdef MOZ_MATHML -nsresult -nsFontXft::GetBoundingMetrics32(const FcChar32* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - aBoundingMetrics.Clear (); - - if (aString && aLength) { - XGlyphInfo glyphInfo; - GetTextExtents32 (aString, aLength, glyphInfo); - aBoundingMetrics.leftBearing = - glyphInfo.x; - aBoundingMetrics.rightBearing = glyphInfo.width - glyphInfo.x; - aBoundingMetrics.ascent = glyphInfo.y; - aBoundingMetrics.descent = glyphInfo.height - glyphInfo.y; - aBoundingMetrics.width = glyphInfo.xOff; - } - return NS_OK; -} -#endif /* MOZ_MATHML */ - -PRInt16 -nsFontXft::GetMaxAscent(void) -{ - NS_PRECONDITION(mXftFont, "FindFont should not return bad fonts"); - return mXftFont->ascent; -} - -PRInt16 -nsFontXft::GetMaxDescent(void) -{ - NS_PRECONDITION(mXftFont, "FindFont should not return bad fonts"); - return mXftFont->descent; -} - -FT_UInt -nsFontXft::CharToGlyphIndex(FcChar32 aChar) -{ - return XftCharIndex(GDK_DISPLAY(), mXftFont, aChar); -} - -// used by DrawStringCallback -nsresult -nsFontXft::DrawStringSpec(FcChar32 *aString, PRUint32 aLen, void *aData) -{ - NS_PRECONDITION(mXftFont, "FindFont should not return bad fonts"); - DrawStringData *data = (DrawStringData *)aData; - - FcChar32 *pstr = aString; - const FcChar32 *end = aString + aLen; - - while(pstr < end) { - nscoord x = data->x + data->xOffset; - nscoord y = data->y; - /* Convert to device coordinate. */ - data->context->GetTranMatrix()->TransformCoord(&x, &y); - - /* position in X is the location offset in the string - plus whatever offset is required for the spacing - argument - */ - - FT_UInt glyph = CharToGlyphIndex(*pstr); - data->drawBuffer->Draw(x, y, mXftFont, glyph); - - if (data->spacing) { - data->xOffset += *data->spacing; - data->spacing += IS_NON_BMP(*pstr) ? 2 : 1; - } - else { - XGlyphInfo info; - XftGlyphExtents(GDK_DISPLAY(), mXftFont, &glyph, 1, &info); - data->xOffset += NSToCoordRound(info.xOff * data->p2t); - } - - ++pstr; - } - return NS_OK; -} - -// class nsFontXftUnicode impl - -nsFontXftUnicode::~nsFontXftUnicode() -{ -} - -PRBool -nsFontXftUnicode::HasChar(PRUint32 aChar) -{ - return FcCharSetHasChar(mCharset, (FcChar32) aChar); -} - -// class nsFontXftCustom impl - -nsFontXftCustom::~nsFontXftCustom() -{ - if (mXftFont && mFT_Face) - XftUnlockFace(mXftFont); -} - -// used by GetWidth32, GetBoundingMetrics32, and TextDimensionCallback -// Convert the input to custom font code before measuring. -nsresult -nsFontXftCustom::GetTextExtents32(const FcChar32 *aString, PRUint32 aLen, - XGlyphInfo &aGlyphInfo) -{ - NS_PRECONDITION(mXftFont, "FindFont should not return bad fonts"); - - nsAutoFcChar32Buffer buffer; - nsresult rv; - PRUint32 destLen = aLen; - PRBool isWide = (mFontInfo->mFontType == eFontTypeCustomWide); - - // we won't use this again. it's safe to cast away const. - rv = ConvertUCS4ToCustom(NS_CONST_CAST(FcChar32 *, aString), - aLen, destLen, mFontInfo->mConverter, - isWide, buffer); - NS_ENSURE_SUCCESS(rv, rv); - - FcChar32 *str = buffer.get(); - - // short cut for the common case - if (isWide) { - XftTextExtents32(GDK_DISPLAY(), mXftFont, str, destLen, &aGlyphInfo); - return NS_OK; - } - - // If FT_SelectCharMap succeeds for MacRoman or Unicode, - // use glyph indices directly for 'narrow' custom encoded fonts. - rv = SetFT_FaceCharmap(); - NS_ENSURE_SUCCESS(rv, rv); - - // replace chars with glyphs in place. - for (PRUint32 i = 0; i < destLen; i++) { - str[i] = FT_Get_Char_Index (mFT_Face, FT_ULong(str[i])); - } - - XftGlyphExtents(GDK_DISPLAY(), mXftFont, str, destLen, &aGlyphInfo); - - return NS_OK; -} - -PRBool -nsFontXftCustom::HasChar(PRUint32 aChar) -{ - return (mFontInfo->mCCMap && - CCMAP_HAS_CHAR_EXT(mFontInfo->mCCMap, aChar)); -} - -FT_UInt -nsFontXftCustom::CharToGlyphIndex(FcChar32 aChar) -{ - if (mFontInfo->mFontType == eFontTypeCustomWide) - return XftCharIndex(GDK_DISPLAY(), mXftFont, aChar); - else - return FT_Get_Char_Index(mFT_Face, aChar); -} - -// used by DrawStringCallback -// Convert the input to custom font code before filling up the buffer. -nsresult -nsFontXftCustom::DrawStringSpec(FcChar32* aString, PRUint32 aLen, - void* aData) -{ - NS_PRECONDITION(mXftFont, "FindFont should not return bad fonts"); - - nsresult rv = NS_OK; - nsAutoFcChar32Buffer buffer; - PRUint32 destLen = aLen; - PRBool isWide = (mFontInfo->mFontType == eFontTypeCustomWide); - - rv = ConvertUCS4ToCustom(aString, aLen, destLen, mFontInfo->mConverter, - isWide, buffer); - NS_ENSURE_SUCCESS(rv, rv); - - if (!isWide) { - // For some narrow fonts(Mathematica, Symbol, and MTExtra), - // what we get back after the conversion is in the encoding - // of a specific FT_Charmap (Apple Roman) instead of Unicode - // so that we can't call XftCharIndex() which regards input - // as a Unicode codepoint. Instead, we have to directly invoke - // FT_Get_Char_Index() with FT_Face corresponding to XftFont - // after setting FT_Charmap to the cmap of our choice(Apple Roman). - rv = SetFT_FaceCharmap(); - NS_ENSURE_SUCCESS(rv, rv); - } - - FcChar32 *str = buffer.get(); - - return nsFontXft::DrawStringSpec(str, destLen, aData); -} - -nsresult -nsFontXftCustom::SetFT_FaceCharmap(void) -{ - NS_PRECONDITION(mXftFont, "FindFont should not return bad fonts"); - - if (mFT_Face) - return NS_OK; - - mFT_Face = XftLockFace(mXftFont); - - NS_ENSURE_TRUE(mFT_Face != nsnull, NS_ERROR_UNEXPECTED); - - // Select FT_Encoding to use for custom narrow fonts in - // glyph index look-up with FT_Get_Char_Index succeeds. - - if (FT_Select_Charmap (mFT_Face, mFontInfo->mFT_Encoding)) - return NS_ERROR_UNEXPECTED; - - return NS_OK; -} - -void -nsAutoDrawSpecBuffer::Draw(nscoord x, nscoord y, XftFont *font, FT_UInt glyph) -{ - if (mSpecPos >= BUFFER_LEN-1) - Flush(); - - // Make sure the coordinates fit into the 16-bit x and y fields of - // XftGlyphFontSpec - NS_ASSERTION(sizeof(short) == sizeof(mSpecBuffer[mSpecPos].x), "Unexpected coordinate type"); - if ((short)x != x || (short)y != y){ - NS_WARNING("ignoring coordinate overflow"); - return; - } - - mSpecBuffer[mSpecPos].x = x; - mSpecBuffer[mSpecPos].y = y; - mSpecBuffer[mSpecPos].font = font; - mSpecBuffer[mSpecPos].glyph = glyph; - ++mSpecPos; -} - -void -nsAutoDrawSpecBuffer::Flush() -{ - if (mSpecPos) { - // Some Xft libraries will crash if none of the glyphs have any - // area. So before we draw, we scan through the glyphs. If we - // find any that have area, we can draw. - for (PRUint32 i = 0; i < mSpecPos; i++) { - XftGlyphFontSpec *sp = &mSpecBuffer[i]; - XGlyphInfo info; - XftGlyphExtents(GDK_DISPLAY(), sp->font, &sp->glyph, 1, &info); - if (info.width && info.height) { - // If we get here it means we found a drawable glyph. We will - // Draw all the remaining glyphs and then break out of the loop - XftDrawGlyphFontSpec(mDraw, mColor, mSpecBuffer+i, mSpecPos-i); - break; - } - } - mSpecPos = 0; - } -} - -// Static functions - -/* static */ -int -CompareFontNames (const void* aArg1, const void* aArg2, void* aClosure) -{ - const PRUnichar* str1 = *((const PRUnichar**) aArg1); - const PRUnichar* str2 = *((const PRUnichar**) aArg2); - - return nsCRT::strcmp(str1, str2); -} - -/* static */ -nsresult -EnumFontsXft(nsIAtom* aLangGroup, const char* aGeneric, - PRUint32* aCount, PRUnichar*** aResult) -{ - FcPattern *pat = NULL; - FcObjectSet *os = NULL; - FcFontSet *fs = NULL; - nsresult rv = NS_ERROR_FAILURE; - - PRUnichar **array = NULL; - PRUint32 narray = 0; - PRInt32 serif = 0, sansSerif = 0, monospace = 0, nGenerics; - - *aCount = 0; - *aResult = nsnull; - - pat = FcPatternCreate(); - if (!pat) - goto end; - - os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, NULL); - if (!os) - goto end; - - // take the pattern and add the lang group to it - if (aLangGroup) - NS_AddLangGroup(pat, aLangGroup); - - // get the font list - fs = FcFontList(0, pat, os); - - if (!fs) - goto end; - - // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and - // "monospace", slightly different from CSS's 5. - if (!aGeneric) - serif = sansSerif = monospace = 1; - else if (!strcmp(aGeneric, "serif")) - serif = 1; - else if (!strcmp(aGeneric, "sans-serif")) - sansSerif = 1; - else if (!strcmp(aGeneric, "monospace")) - monospace = 1; - else if (!strcmp(aGeneric, "cursive") || !strcmp(aGeneric, "fantasy")) - serif = sansSerif = 1; - else - NS_NOTREACHED("unexpected generic family"); - nGenerics = serif + sansSerif + monospace; - - array = NS_STATIC_CAST(PRUnichar **, - nsMemory::Alloc((fs->nfont + nGenerics) * sizeof(PRUnichar *))); - if (!array) - goto end; - - if (serif) { - PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("serif")); - if (!name) - goto end; - array[narray++] = name; - } - - if (sansSerif) { - PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("sans-serif")); - if (!name) - goto end; - array[narray++] = name; - } - - if (monospace) { - PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("monospace")); - if (!name) - goto end; - array[narray++] = name; - } - - for (int i=0; i < fs->nfont; ++i) { - char *family; - - // if there's no family, just move to the next iteration - if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0, - (FcChar8 **) &family) != FcResultMatch) { - continue; - } - - // fontconfig always returns family names in UTF-8 - PRUnichar* name = UTF8ToNewUnicode(nsDependentCString(family)); - - if (!name) - goto end; - - array[narray++] = name; - } - - NS_QuickSort(array + nGenerics, narray - nGenerics, sizeof (PRUnichar*), - CompareFontNames, nsnull); - - *aCount = narray; - if (narray) - *aResult = array; - else - nsMemory::Free(array); - - rv = NS_OK; - - end: - if (NS_FAILED(rv) && array) { - while (narray) - nsMemory::Free (array[--narray]); - nsMemory::Free (array); - } - if (pat) - FcPatternDestroy(pat); - if (os) - FcObjectSetDestroy(os); - if (fs) - FcFontSetDestroy(fs); - - return rv; -} - -/* static */ -void -ConvertCharToUCS4(const char *aString, PRUint32 aLength, - nsAutoFcChar32Buffer &aOutBuffer, PRUint32 *aOutLen) -{ - *aOutLen = 0; - FcChar32 *outBuffer; - - if (!aOutBuffer.EnsureElemCapacity(aLength)) - return; - outBuffer = aOutBuffer.get(); - - for (PRUint32 i = 0; i < aLength; ++i) { - outBuffer[i] = PRUint8(aString[i]); // to convert char >= 0x80 correctly - } - - *aOutLen = aLength; -} - -// Convert the incoming string into an array of UCS4 chars - -/* static */ -void -ConvertUnicharToUCS4(const PRUnichar *aString, PRUint32 aLength, - nsAutoFcChar32Buffer &aOutBuffer, PRUint32 *aOutLen) -{ - *aOutLen = 0; - FcChar32 *outBuffer; - - if (!aOutBuffer.EnsureElemCapacity(aLength)) - return; - outBuffer = aOutBuffer.get(); - - PRUint32 outLen = 0; - - // Walk the passed in string looking for surrogates to convert to - // their full ucs4 representation. - for (PRUint32 i = 0; i < aLength; ++i) { - PRUnichar c = aString[i]; - - // Optimized for the non-surrogate case - if (IS_NON_SURROGATE(c)) { - outBuffer[outLen] = c; - } - else if (NS_IS_HIGH_SURROGATE(aString[i])) { - if (i + 1 < aLength && NS_IS_LOW_SURROGATE(aString[i+1])) { - outBuffer[outLen] = SURROGATE_TO_UCS4(c, aString[i + 1]); - ++i; - } - else { // Unpaired high surrogate - outBuffer[outLen] = UCS2_REPLACEMENT; - } - } - else if (NS_IS_LOW_SURROGATE(aString[i])) { // Unpaired low surrogate? - outBuffer[outLen] = UCS2_REPLACEMENT; - } - - outLen++; - } - - *aOutLen = outLen; -} - -#ifdef MOZ_WIDGET_GTK2 -/* static */ -void -GdkRegionSetXftClip(GdkRegion *aGdkRegion, XftDraw *aDraw) -{ - GdkRectangle *rects = nsnull; - int n_rects = 0; - - gdk_region_get_rectangles(aGdkRegion, &rects, &n_rects); - - XRectangle *xrects = g_new(XRectangle, n_rects); - - for (int i=0; i < n_rects; ++i) { - xrects[i].x = CLAMP(rects[i].x, G_MINSHORT, G_MAXSHORT); - xrects[i].y = CLAMP(rects[i].y, G_MINSHORT, G_MAXSHORT); - xrects[i].width = CLAMP(rects[i].width, G_MINSHORT, G_MAXSHORT); - xrects[i].height = CLAMP(rects[i].height, G_MINSHORT, G_MAXSHORT); - } - - XftDrawSetClipRectangles(aDraw, 0, 0, xrects, n_rects); - - g_free(xrects); - g_free(rects); -} -#endif /* MOZ_WIDGET_GTK2 */ - -// Helper to determine if a font has a private encoding that we know -// something about -/* static */ -nsresult -GetEncoding(const char *aFontName, char **aEncoding, nsXftFontType &aType, - FT_Encoding &aFTEncoding) -{ - // below is a list of common used name for startup - if ((!strcmp(aFontName, "Helvetica" )) || - (!strcmp(aFontName, "Times" )) || - (!strcmp(aFontName, "Times New Roman" )) || - (!strcmp(aFontName, "Courier New" )) || - (!strcmp(aFontName, "Courier" )) || - (!strcmp(aFontName, "Arial" )) || - (!strcmp(aFontName, "MS P Gothic" )) || - (!strcmp(aFontName, "Verdana" ))) { - // error mean do not get a special encoding - return NS_ERROR_NOT_AVAILABLE; - } - - nsCAutoString name; - name.Assign(NS_LITERAL_CSTRING("encoding.") + - nsDependentCString(aFontName) + NS_LITERAL_CSTRING(".ttf")); - - name.StripWhitespace(); - ToLowerCase(name); - - // if we have not init the property yet, init it right now. - if (!gFontEncodingProperties) - NS_LoadPersistentPropertiesFromURISpec(&gFontEncodingProperties, - NS_LITERAL_CSTRING("resource://gre/res/fonts/fontEncoding.properties")); - - nsAutoString encoding; - *aEncoding = nsnull; - if (gFontEncodingProperties) { - nsresult rv = gFontEncodingProperties->GetStringProperty(name, - encoding); - if (NS_FAILED(rv)) - return NS_ERROR_NOT_AVAILABLE; // Unicode font - - // '.wide' at the end indicates 'wide' font. - if (encoding.Length() > 5 && - StringEndsWith(encoding, NS_LITERAL_STRING(".wide"))) { - aType = eFontTypeCustomWide; - encoding.Truncate(encoding.Length() - 5); - } - else { - aType = eFontTypeCustom; - - // Mathematica and TeX CM truetype fonts have both Apple Roman - // (PID=1, EID=0) and Unicode (PID=3, EID=1) cmaps. In the - // former, Unicode cmap uses codepoints in PUA beginning - // at U+F000 not representable in a single byte encoding - // like MathML encodings. ( On the other hand, TeX CM fonts - // have 'pseudo-Unicode' cmap with codepoints below U+0100.) - // Unicode to font encoding converters for MathML map input - // Unicode codepoints to 'pseudo-glyph indices' in Apple Roman - // for Mathematica, Symbol and MTExtra fonts while it maps - // input Unicode codepoints to 'pseudo-glyph indices' in - // 'Unicode cmap' for TeX CM fonts. Therefore we have to select - // different FT_Encoding for two groups to guarantee that - // glyph index look-up with FT_Get_Char_Index succeeds for - // all MathML fonts. Instead of hard-coding this relation, - // it's put in fontEncoding.properties file and is parsed here. - - nsAutoString ftCharMap; - nsresult rv = gFontEncodingProperties->GetStringProperty( - Substring(name, 0, name.Length() - 4) + - NS_LITERAL_CSTRING(".ftcmap"), ftCharMap); - - if (NS_FAILED(rv)) - aFTEncoding = ft_encoding_none; - else if (ftCharMap.LowerCaseEqualsLiteral("mac_roman")) - aFTEncoding = ft_encoding_apple_roman; - else if (ftCharMap.LowerCaseEqualsLiteral("unicode")) - aFTEncoding = ft_encoding_unicode; - } - - // encoding name is always in US-ASCII so that there's no loss here. - *aEncoding = ToNewCString(encoding); - if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) { - printf("\t\tc> it's %s and encoding is %s\n", - aType==eFontTypeCustom ? "narrow" : "wide", *aEncoding); - } - - return NS_OK; - } - - return NS_ERROR_NOT_AVAILABLE; -} - -/* static */ -static nsresult -GetConverter(const char* aEncoding, nsIUnicodeEncoder **aConverter) -{ - nsresult rv; - - if (!gCharsetManager) { - CallGetService(kCharsetConverterManagerCID, &gCharsetManager); - if (!gCharsetManager) { - FreeGlobals(); - return NS_ERROR_FAILURE; - } - } - - // encoding name obtained from fontEncoding.properties is - // canonical so that we don't need the alias resolution. use 'Raw' - // version. - rv = gCharsetManager->GetUnicodeEncoderRaw(aEncoding, aConverter); - NS_ENSURE_SUCCESS(rv, rv); - if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) { - printf("\t\tc> got the converter for %s \n", aEncoding); - } - - return (*aConverter)->SetOutputErrorBehavior( - (*aConverter)->kOnError_Replace, nsnull, '?'); -} - - -/* static */ -nsresult -FreeGlobals(void) -{ - gInitialized = 0; - - NS_IF_RELEASE(gFontEncodingProperties); - NS_IF_RELEASE(gCharsetManager); - - gFontXftMaps.Clear(); - - return NS_OK; -} - -nsFontXftInfo* -GetFontXftInfo(FcPattern* aPattern) -{ - const char* family; - - // If there's no family, just treat it as if it's a normal Unicode font - if (FcPatternGetString(aPattern, FC_FAMILY, 0, (FcChar8 **) &family) - != FcResultMatch) { - return nsnull; - } - - NS_ASSERTION(gFontXftMaps.IsInitialized(), "gFontXMaps should be init'd by now."); - - nsFontXftInfo* info; - - // cached entry found. - if (gFontXftMaps.Get(family, &info)) - return info; - - nsCOMPtr converter; - nsXftFontType fontType = eFontTypeUnicode; - nsXPIDLCString encoding; - FT_Encoding ftEncoding = ft_encoding_unicode; - PRUint16* ccmap = nsnull; - - // See if a font has a custom/private encoding by matching - // its family name against the list in fontEncoding.properties - // with GetEncoding(). It also sets fonttype (wide or narrow). - // Then get the converter and see if has a valid coverage map. - - // XXX these two if-statements used to be logically AND'ed, but - // string changes (bug 231995) made it impossible to use getter_Copies(encoding) - // and encoding.get() in a single statement. Until Darin comes up with - // a solution, we need to split it into two if-statements. (bug 234908) - if (NS_SUCCEEDED(GetEncoding(family, getter_Copies(encoding), - fontType, ftEncoding))) { - if (NS_SUCCEEDED(GetConverter(encoding.get(), - getter_AddRefs(converter)))) { - nsCOMPtr mapper(do_QueryInterface(converter)); - if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) { - printf("\t\tc> got the converter and CMap :%s !!\n", - encoding.get()); - } - - if (mapper) { - ccmap = MapperToCCMap(mapper); - } - } - } - - // XXX Need to check if an identical map has already been added - Bug 75260 - // For Xft, this doesn't look as critical as in GFX Win. - - info = new nsFontXftInfo; - if (!info) - return nsnull; - - info->mCCMap = ccmap; - info->mConverter = converter; - info->mFontType = fontType; - info->mFT_Encoding = ftEncoding; - - gFontXftMaps.Put(family, info); - - return info; -} - -/* static */ -// Convert input UCS4 string to "Pseudo-UCS4" string made of -// custom font-specific codepoints with Unicode converter. -nsresult -ConvertUCS4ToCustom(FcChar32 *aSrc, PRUint32 aSrcLen, - PRUint32& aDestLen, nsIUnicodeEncoder *aConverter, - PRBool aIsWide, nsAutoFcChar32Buffer& aResult) -{ - nsresult rv = NS_OK; - - nsCOMPtr converter = aConverter; - if (!converter ) - return NS_ERROR_UNEXPECTED; - - // Convert to UTF-16 because UnicodeEncoder expects input to be in - // UTF-16. We can get away with in-place replacement because - // UTF-16 is at most as long as UCS-4 so that UCS-4(source) buffer - // pointer is always ahead of UTF-16(target) buffer pointer and we - // won't revisit the buffer we already processed. - - PRUnichar *utf16Src = NS_REINTERPRET_CAST(PRUnichar *, aSrc); - PRUnichar *utf16Ptr = utf16Src; - for (PRUint32 i = 0; i < aSrcLen; ++i, ++utf16Ptr) { - if (!IS_NON_BMP(aSrc[i])) { - *utf16Ptr = PRUnichar(aSrc[i]); - } - else { - *utf16Ptr = H_SURROGATE(aSrc[i]); - *++utf16Ptr = L_SURROGATE(aSrc[i]); - } - } - - PRInt32 utf16SrcLen = utf16Ptr - utf16Src; - PRInt32 medLen = utf16SrcLen; - // Length can increase for 'Wide' custom fonts. - if (aIsWide && - NS_FAILED(aConverter->GetMaxLength(utf16Src, utf16SrcLen, &medLen))) { - return NS_ERROR_UNEXPECTED; - } - - nsAutoBuffer medBuffer; - if (!medBuffer.EnsureElemCapacity(medLen)) - return NS_ERROR_OUT_OF_MEMORY; - char *med = medBuffer.get(); - - // Convert utf16Src to font-specific encoding with mConverter. - rv = converter->Convert(utf16Src, &utf16SrcLen, med, &medLen); - NS_ENSURE_SUCCESS(rv, rv); - - // Put pseudo-unicode str. into font specific pseudo-UCS-4 str. - if (aIsWide) { -#ifdef IS_LITTLE_ENDIAN - // Convert BE UTF-16 to LE UTF-16 for 'wide' custom fonts - char* pstr = med; - while (pstr < med + medLen) { - PRUint8 tmp = pstr[0]; - pstr[0] = pstr[1]; - pstr[1] = tmp; - pstr += 2; // swap every two bytes - } -#endif - // Convert 16bit custom font codes to UCS4 - ConvertUnicharToUCS4(NS_REINTERPRET_CAST(PRUnichar *, med), - 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); - rv = aDestLen ? rv : NS_ERROR_OUT_OF_MEMORY; - } - - return rv; -} diff --git a/gfx/src/gtk/nsFontMetricsXft.h b/gfx/src/gtk/nsFontMetricsXft.h deleted file mode 100644 index a9c5a5f28c9f..000000000000 --- a/gfx/src/gtk/nsFontMetricsXft.h +++ /dev/null @@ -1,350 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard . - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsIFontMetrics.h" -#include "nsIFontEnumerator.h" -#include "nsCRT.h" -#include "nsIAtom.h" -#include "nsString.h" -#include "nsVoidArray.h" -#include "nsIFontMetricsGTK.h" - -#include -#include - -class nsFontXft; -class nsFontMetricsXft; - -typedef nsresult (nsFontMetricsXft::*GlyphEnumeratorCallback) - (const FcChar32 *aString, - PRUint32 aLen, nsFontXft *aFont, - void *aData); - -class nsFontMetricsXft : public nsIFontMetricsGTK -{ -public: - nsFontMetricsXft(); - virtual ~nsFontMetricsXft(); - - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - // nsISupports - NS_DECL_ISUPPORTS - - // nsIFontMetrics - NS_IMETHOD Init (const nsFont& aFont, nsIAtom* aLangGroup, - nsIDeviceContext *aContext); - NS_IMETHOD Destroy(); - NS_IMETHOD GetLangGroup (nsIAtom** aLangGroup); - NS_IMETHOD GetFontHandle (nsFontHandle &aHandle); - - NS_IMETHOD GetXHeight (nscoord& aResult) - { aResult = mXHeight; return NS_OK; }; - - NS_IMETHOD GetSuperscriptOffset (nscoord& aResult) - { aResult = mSuperscriptOffset; - return NS_OK; }; - - NS_IMETHOD GetSubscriptOffset (nscoord& aResult) - { aResult = mSubscriptOffset; - return NS_OK; }; - - NS_IMETHOD GetStrikeout (nscoord& aOffset, nscoord& aSize) - { aOffset = mStrikeoutOffset; - aSize = mStrikeoutSize; - return NS_OK; }; - - NS_IMETHOD GetUnderline (nscoord& aOffset, nscoord& aSize) - { aOffset = mUnderlineOffset; - aSize = mUnderlineSize; - return NS_OK; }; - - NS_IMETHOD GetHeight (nscoord &aHeight) - { aHeight = mMaxHeight; - return NS_OK; }; - - NS_IMETHOD GetNormalLineHeight (nscoord &aHeight) - { aHeight = mEmHeight + mLeading; - return NS_OK; }; - - NS_IMETHOD GetLeading (nscoord &aLeading) - { aLeading = mLeading; - return NS_OK; }; - - NS_IMETHOD GetEmHeight (nscoord &aHeight) - { aHeight = mEmHeight; - return NS_OK; }; - - NS_IMETHOD GetEmAscent (nscoord &aAscent) - { aAscent = mEmAscent; - return NS_OK; }; - - NS_IMETHOD GetEmDescent (nscoord &aDescent) - { aDescent = mEmDescent; - return NS_OK; }; - - NS_IMETHOD GetMaxHeight (nscoord &aHeight) - { aHeight = mMaxHeight; - return NS_OK; }; - - NS_IMETHOD GetMaxAscent (nscoord &aAscent) - { aAscent = mMaxAscent; - return NS_OK; }; - - NS_IMETHOD GetMaxDescent (nscoord &aDescent) - { aDescent = mMaxDescent; - return NS_OK; }; - - NS_IMETHOD GetMaxAdvance (nscoord &aAdvance) - { aAdvance = mMaxAdvance; - return NS_OK; }; - - NS_IMETHOD GetSpaceWidth (nscoord &aSpaceCharWidth) - { aSpaceCharWidth = mSpaceWidth; - return NS_OK; }; - - NS_IMETHOD GetAveCharWidth (nscoord &aAveCharWidth) - { aAveCharWidth = mAveCharWidth; - return NS_OK; }; - - 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); - - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - virtual nsresult GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext); - - virtual nsresult 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, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface); - -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - nsRenderingContextGTK *aContext); - virtual nsresult GetBoundingMetrics(const PRUnichar *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - PRInt32 *aFontID, - nsRenderingContextGTK *aContext); -#endif /* MOZ_MATHML */ - - virtual GdkFont* GetCurrentGDKFont(void); - - virtual nsresult SetRightToLeftText(PRBool aIsRTL); - virtual PRBool GetRightToLeftText(); - - virtual nsresult GetClusterInfo(const PRUnichar *aText, - PRUint32 aLength, - PRUint8 *aClusterStarts); - - virtual PRInt32 GetPosition(const PRUnichar *aText, - PRUint32 aLength, - nsPoint aPt); - - virtual nsresult GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - - virtual nsresult GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - - // get hints for the font - static PRUint32 GetHints (void); - - // drawing surface methods - static nsresult FamilyExists (nsIDeviceContext *aDevice, - const nsString &aName); - - nsresult DrawStringCallback (const FcChar32 *aString, PRUint32 aLen, - nsFontXft *aFont, void *aData); - nsresult TextDimensionsCallback (const FcChar32 *aString, PRUint32 aLen, - nsFontXft *aFont, void *aData); - nsresult GetWidthCallback (const FcChar32 *aString, PRUint32 aLen, - nsFontXft *aFont, void *aData); -#ifdef MOZ_MATHML - nsresult BoundingMetricsCallback (const FcChar32 *aString, PRUint32 aLen, - nsFontXft *aFont, void *aData); -#endif /* MOZ_MATHML */ - -private: - enum FontMatch { - eNoMatch, - eBestMatch, - eAllMatching - }; - - // local methods - nsresult RealizeFont (void); - nsresult CacheFontMetrics (void); - // Guaranteed to return either null or a font on which |GetXftFont| - // returns non-null. - nsFontXft *FindFont (PRUint32); - void SetupFCPattern (void); - void DoMatch (PRBool aMatchAll); - - gint RawGetWidth (const PRUnichar* aString, - PRUint32 aLength); - nsresult SetupMiniFont (void); - nsresult DrawUnknownGlyph (FcChar32 aChar, - nscoord aX, - nscoord aY, - XftColor *aColor, - XftDraw *aDraw); - nsresult EnumerateXftGlyphs (const FcChar32 *aString, - PRUint32 aLen, - GlyphEnumeratorCallback aCallback, - void *aCallbackData); - nsresult EnumerateGlyphs (const char *aString, - PRUint32 aLen, - GlyphEnumeratorCallback aCallback, - void *aCallbackData); - nsresult EnumerateGlyphs (const PRUnichar *aString, - PRUint32 aLen, - GlyphEnumeratorCallback aCallback, - void *aCallbackData); - void PrepareToDraw (nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface, - XftDraw **aDraw, XftColor &aColor); - - // called when enumerating font families - static PRBool EnumFontCallback (const nsString &aFamily, - PRBool aIsGeneric, void *aData); - - - // generic font metrics class bits - nsCStringArray mFontList; - nsAutoVoidArray mFontIsGeneric; - - nsIDeviceContext *mDeviceContext; - nsCOMPtr mLangGroup; - nsCString *mGenericFont; - float mPixelSize; - - nsCAutoString mDefaultFont; - - // private to DoMatch and FindFont; this array may contain fonts - // for which |GetXftFont| returns null (which are not allowed outside - // of those two functions). - nsVoidArray mLoadedFonts; - - // Xft-related items - nsFontXft *mWesternFont; - FcPattern *mPattern; - FontMatch mMatchType; - - // for rendering unknown fonts - XftFont *mMiniFont; - nscoord mMiniFontWidth; - nscoord mMiniFontHeight; - nscoord mMiniFontPadding; - nscoord mMiniFontYOffset; - nscoord mMiniFontAscent; - nscoord mMiniFontDescent; - - // Cached font metrics - nscoord mXHeight; - nscoord mSuperscriptOffset; - nscoord mSubscriptOffset; - nscoord mStrikeoutOffset; - nscoord mStrikeoutSize; - nscoord mUnderlineOffset; - nscoord mUnderlineSize; - nscoord mMaxHeight; - nscoord mLeading; - nscoord mEmHeight; - nscoord mEmAscent; - nscoord mEmDescent; - nscoord mMaxAscent; - nscoord mMaxDescent; - nscoord mMaxAdvance; - nscoord mSpaceWidth; - nscoord mAveCharWidth; - PRInt32 mMaxStringLength; -}; - -class nsFontEnumeratorXft : public nsIFontEnumerator -{ -public: - nsFontEnumeratorXft(); - NS_DECL_ISUPPORTS - NS_DECL_NSIFONTENUMERATOR -}; diff --git a/gfx/src/gtk/nsGCCache.cpp b/gfx/src/gtk/nsGCCache.cpp deleted file mode 100644 index 6e01fa430e61..000000000000 --- a/gfx/src/gtk/nsGCCache.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla browser. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Stuart Parmenter - * Mike Shaver - * Tomi Leppikangas - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include "nsGCCache.h" -#include "nsISupportsUtils.h" -#include -#include -#include -/* The GC cache is shared among all windows, since it doesn't hog - any scarce resources (like colormap entries.) */ - -GdkRegion *nsGCCache::copyRegion = NULL; - -nsGCCache::nsGCCache() -{ - MOZ_COUNT_CTOR(nsGCCache); - PR_INIT_CLIST(&GCCache); - PR_INIT_CLIST(&GCFreeList); - for (int i = 0; i < GC_CACHE_SIZE; i++) { - GCCacheEntry *entry = new GCCacheEntry(); - entry->gc=NULL; - PR_INSERT_LINK(&entry->clist, &GCFreeList); - } - DEBUG_METER(memset(&GCCacheStats, 0, sizeof(GCCacheStats));) -} - -/* static */ void -nsGCCache::Shutdown() -{ - if (copyRegion) { - gdk_region_destroy(copyRegion); - copyRegion = nsnull; - } -} - -void -nsGCCache::move_cache_entry(PRCList *clist) -{ - /* thread on the freelist, at the front */ - PR_REMOVE_LINK(clist); - PR_INSERT_LINK(clist, &GCFreeList); -} - -void -nsGCCache::free_cache_entry(PRCList *clist) -{ - GCCacheEntry *entry = (GCCacheEntry *)clist; - gdk_gc_unref(entry->gc); - if (entry->clipRegion) - gdk_region_destroy(entry->clipRegion); - - /* thread on the freelist, at the front */ - PR_REMOVE_LINK(clist); - memset(entry, 0, sizeof(*entry)); - PR_INSERT_LINK(clist, &GCFreeList); -} - -nsGCCache::~nsGCCache() -{ - PRCList *head; - - MOZ_COUNT_DTOR(nsGCCache); - - ReportStats(); - - while (!PR_CLIST_IS_EMPTY(&GCCache)) { - head = PR_LIST_HEAD(&GCCache); - if (head == &GCCache) - break; - free_cache_entry(head); - } - - while (!PR_CLIST_IS_EMPTY(&GCFreeList)) { - head = PR_LIST_HEAD(&GCFreeList); - if (head == &GCFreeList) - break; - PR_REMOVE_LINK(head); - delete (GCCacheEntry *)head; - } -} - -void -nsGCCache::ReportStats() { - DEBUG_METER( - fprintf(stderr, "GC Cache:\n\thits:"); - int hits = 0; - for (int i = 0; i < GC_CACHE_SIZE; i++) { - fprintf(stderr, " %4d", GCCacheStats.hits[i]); - hits+=GCCacheStats.hits[i]; - } - int total = hits + GCCacheStats.misses; - float percent = float(float(hits) / float(total)); - percent *= 100; - fprintf(stderr, "\n\thits: %d, misses: %d, hit percent: %f%%\n", - hits, GCCacheStats.misses, percent); - ); -} - -/* Dispose of entries matching the given flags, compressing the GC cache */ -void nsGCCache::Flush(unsigned long flags) -{ - while (!PR_CLIST_IS_EMPTY(&GCCache)) { - PRCList *head = PR_LIST_HEAD(&GCCache); - if (head == &GCCache) - break; - GCCacheEntry *entry = (GCCacheEntry *)head; - if (entry->flags & flags) - free_cache_entry(head); - } -} - -GdkGC *nsGCCache::GetGC(GdkWindow *window, GdkGCValues *gcv, GdkGCValuesMask flags, GdkRegion *clipRegion) -{ - - PRCList *iter; - GCCacheEntry *entry; - DEBUG_METER(int i = 0;) - - for (iter = PR_LIST_HEAD(&GCCache); iter != &GCCache; - iter = PR_NEXT_LINK(iter)) { - - entry = (GCCacheEntry *)iter; - if (flags == entry->flags && - !memcmp (gcv, &entry->gcv, sizeof (*gcv))) { - /* if there's a clipRegion, we have to match */ - - if ((clipRegion && entry->clipRegion && - gdk_region_equal(clipRegion, entry->clipRegion)) || - /* and if there isn't, we can't have one */ - (!clipRegion && !entry->clipRegion)) { - - /* move to the front of the list, if needed */ - if (iter != PR_LIST_HEAD(&GCCache)) { - PR_REMOVE_LINK(iter); - PR_INSERT_LINK(iter, &GCCache); - } - DEBUG_METER(GCCacheStats.hits[i]++;) - return gdk_gc_ref(entry->gc); - } - } - DEBUG_METER(++i;) - } - - /* might need to forcibly free the LRU cache entry */ - if (PR_CLIST_IS_EMPTY(&GCFreeList)) { - DEBUG_METER(GCCacheStats.reclaim++); - move_cache_entry(PR_LIST_TAIL(&GCCache)); - } - - DEBUG_METER(GCCacheStats.misses++;) - - iter = PR_LIST_HEAD(&GCFreeList); - PR_REMOVE_LINK(iter); - PR_INSERT_LINK(iter, &GCCache); - entry = (GCCacheEntry *)iter; - - if (!entry->gc) { - // No old GC, greate new - entry->gc = gdk_gc_new_with_values(window, gcv, flags); - entry->flags = flags; - entry->gcv = *gcv; - entry->clipRegion = NULL; - //printf("creating new gc=%X\n",entry->gc); - } - else if ( G_OBJECT(entry->gc)->ref_count > 1 ) { - // Old GC still in use, create new - gdk_gc_unref(entry->gc); - entry->gc=gdk_gc_new_with_values(window, gcv, flags); - entry->flags = flags; - entry->gcv = *gcv; - entry->clipRegion = NULL; - //printf("creating new (use)gc=%X\n",entry->gc); - } - else { - ReuseGC(entry, gcv, flags); - } - - if (clipRegion) { - entry->clipRegion = gdk_region_copy(clipRegion); - if (entry->clipRegion) - gdk_gc_set_clip_region(entry->gc, entry->clipRegion); - /* XXX what if it fails? */ - } - - return gdk_gc_ref(entry->gc); -} - -void nsGCCache::ReuseGC(GCCacheEntry *entry, GdkGCValues *gcv, GdkGCValuesMask flags) -{ - // We have old GC, reuse it and check what - // we have to change - - GdkGCValues xvalues; - int xvalues_mask = 0; - - if (entry->clipRegion) { - // set it to none here and then set the clip region with - // gdk_gc_set_clip_region in GetGC() - xvalues.clip_mask = None; - xvalues_mask |= GDK_GC_CLIP_MASK; - gdk_region_destroy(entry->clipRegion); - entry->clipRegion = NULL; - } - - if (entry->gcv.foreground.pixel != gcv->foreground.pixel) { - xvalues.foreground.pixel = gcv->foreground.pixel; - xvalues_mask |= GDK_GC_FOREGROUND; - } - - if (entry->gcv.function != gcv->function) { - xvalues.function = gcv->function; - xvalues_mask |= GDK_GC_FUNCTION; - } - - if(entry->gcv.font != gcv->font && flags & GDK_GC_FONT) { - xvalues.font = gcv->font; - xvalues_mask |= GDK_GC_FONT; - } - - if (entry->gcv.line_style != gcv->line_style) { - xvalues.line_style = gcv->line_style; - xvalues_mask |= GDK_GC_LINE_STYLE; - } - - if (xvalues_mask != 0) { - gdk_gc_set_values(entry->gc, &xvalues, (GdkGCValuesMask)xvalues_mask); - } - - entry->flags = flags; - entry->gcv = *gcv; -} diff --git a/gfx/src/gtk/nsGCCache.h b/gfx/src/gtk/nsGCCache.h deleted file mode 100644 index cb37c1497f47..000000000000 --- a/gfx/src/gtk/nsGCCache.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla browser. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Stuart Parmenter - * Mike Shaver - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include -#include "prclist.h" - -#ifndef nsGCCache_h___ -#define nsGCCache_h___ - -#define countof(x) ((int)(sizeof(x) / sizeof (*x))) -#define GC_CACHE_SIZE 10 - -#ifdef DEBUG -#define DEBUG_METER(x) x -#else -#define DEBUG_METER(x) -#endif - -struct GCCacheEntry -{ - PRCList clist; - GdkGCValuesMask flags; - GdkGCValues gcv; - GdkRegion *clipRegion; - GdkGC *gc; -}; - -class nsGCCache -{ - public: - nsGCCache(); - virtual ~nsGCCache(); - - static void Shutdown(); - - void Flush(unsigned long flags); - - GdkGC *GetGC(GdkWindow *window, GdkGCValues *gcv, GdkGCValuesMask flags, GdkRegion *clipRegion); - -private: - void ReuseGC(GCCacheEntry *entry, GdkGCValues *gcv, GdkGCValuesMask flags); - PRCList GCCache; - PRCList GCFreeList; - void free_cache_entry(PRCList *clist); - void move_cache_entry(PRCList *clist); - static GdkRegion *copyRegion; - void ReportStats(); - - DEBUG_METER( - struct { - int hits[GC_CACHE_SIZE]; - int misses; - int reclaim; - } GCCacheStats; - ) - -}; - -#endif diff --git a/gfx/src/gtk/nsGdkUtils.cpp b/gfx/src/gtk/nsGdkUtils.cpp deleted file mode 100644 index fc3b65d74751..000000000000 --- a/gfx/src/gtk/nsGdkUtils.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Stuart Parmenter - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsGdkUtils.h" -#include -#include - -void -my_gdk_draw_text(GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const gchar *text, - gint text_length) -{ - g_return_if_fail (drawable != NULL); - g_return_if_fail (font != NULL); - g_return_if_fail (gc != NULL); - g_return_if_fail (text != NULL); - - if (GDK_IS_WINDOW(drawable) && GDK_WINDOW_OBJECT(drawable)->destroyed) - return; - - if (font->type == GDK_FONT_FONT) - { - XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT(font); - - // gdk does this... we don't need it.. - // XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid); - - // We clamp the sizes down to 32768 which is the maximum width of - // a window. Even if a font was 1 pixel high and started at the - // left, the maximum size of a draw request could only be 32k. - - if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) - { - XDrawString (GDK_WINDOW_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable), - GDK_GC_XGC(gc), x, y, text, MIN(text_length, 32768)); - } - else - { - XDrawString16 (GDK_WINDOW_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable), - GDK_GC_XGC(gc), x, y, (XChar2b *) text, - MIN((text_length / 2), 32768)); - } - } - else if (font->type == GDK_FONT_FONTSET) - { - XFontSet fontset = (XFontSet) GDK_FONT_XFONT(font); - XmbDrawString (GDK_WINDOW_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable), - fontset, GDK_GC_XGC(gc), x, y, text, text_length); - } - else - g_error("undefined font type\n"); -} diff --git a/gfx/src/gtk/nsGdkUtils.h b/gfx/src/gtk/nsGdkUtils.h deleted file mode 100644 index 3094496b93b6..000000000000 --- a/gfx/src/gtk/nsGdkUtils.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 1; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsGdkUtils_h___ -#define nsGdkUtils_h___ - -#include - -// replacment for gdk_draw_text that doesn't do XSetFont -void my_gdk_draw_text(GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const gchar *text, - gint text_length); - -#endif /* nsGdkUtils_h___ */ diff --git a/gfx/src/gtk/nsGfxFactoryGTK.cpp b/gfx/src/gtk/nsGfxFactoryGTK.cpp deleted file mode 100644 index cc13e68e447f..000000000000 --- a/gfx/src/gtk/nsGfxFactoryGTK.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard. - * Portions created by the Initial Developer are Copyright (C) 2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Christopher Blizzzard - * Roland Mainz - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "gfx-config.h" -#include "nsIGenericFactory.h" -#include "nsIModule.h" -#include "nsCOMPtr.h" -#include "nsGfxCIID.h" - -#include "nsBlender.h" -#include "nsRenderingContextGTK.h" -#include "nsDeviceContextGTK.h" -#include "nsScriptableRegion.h" -#include "nsDeviceContextGTK.h" -#include "nsImageGTK.h" -#include "nsFontList.h" -#include "nsRegionGTK.h" -#include "nsGCCache.h" -#ifdef MOZ_ENABLE_PANGO -#include "nsFontMetricsPango.h" -#endif -#ifdef MOZ_ENABLE_XFT -#include "nsFontMetricsXft.h" -#endif -#ifdef MOZ_ENABLE_COREXFONTS -#include "nsFontMetricsGTK.h" -#endif -#include "nsFontMetricsUtils.h" -#include "gfxImageFrame.h" -#ifdef MOZ_ENABLE_FREETYPE2 -#include "nsFT2FontCatalog.h" -#include "nsFreeType.h" -#endif - -// objects that just require generic constructors - -NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextGTK) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsRenderingContextGTK) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsImageGTK) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlender) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsRegionGTK) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontList) - -NS_GENERIC_FACTORY_CONSTRUCTOR(gfxImageFrame) -#ifdef MOZ_ENABLE_FREETYPE2 -NS_GENERIC_FACTORY_CONSTRUCTOR(nsFT2FontCatalog) -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFreeType2, Init) -#endif - -// our custom constructors - -static nsresult -nsFontMetricsConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) -{ - nsIFontMetrics *result; - - if (!aResult) - return NS_ERROR_NULL_POINTER; - - *aResult = nsnull; - - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - -#ifdef MOZ_ENABLE_PANGO - if (NS_IsPangoEnabled()) { - result = new nsFontMetricsPango(); - if (!result) - return NS_ERROR_OUT_OF_MEMORY; - } else { -#endif -#ifdef MOZ_ENABLE_XFT - if (NS_IsXftEnabled()) { - result = new nsFontMetricsXft(); - if (!result) - return NS_ERROR_OUT_OF_MEMORY; - } else { -#endif -#ifdef MOZ_ENABLE_COREXFONTS - result = new nsFontMetricsGTK(); - if (!result) - return NS_ERROR_OUT_OF_MEMORY; -#endif -#ifdef MOZ_ENABLE_XFT - } -#endif -#ifdef MOZ_ENABLE_PANGO - } -#endif - - NS_ADDREF(result); - nsresult rv = result->QueryInterface(aIID, aResult); - NS_RELEASE(result); - - return rv; -} - -static nsresult -nsFontEnumeratorConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) -{ - nsIFontEnumerator *result; - - if (!aResult) - return NS_ERROR_NULL_POINTER; - - *aResult = nsnull; - - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - -#ifdef MOZ_ENABLE_PANGO - if (NS_IsPangoEnabled()) { - result = new nsFontEnumeratorPango(); - if (!result) - return NS_ERROR_OUT_OF_MEMORY; - } else { -#endif -#ifdef MOZ_ENABLE_XFT - if (NS_IsXftEnabled()) { - result = new nsFontEnumeratorXft(); - if (!result) - return NS_ERROR_OUT_OF_MEMORY; - } else { -#endif -#ifdef MOZ_ENABLE_COREXFONTS - result = new nsFontEnumeratorGTK(); - if (!result) - return NS_ERROR_OUT_OF_MEMORY; -#endif -#ifdef MOZ_ENABLE_XFT - } -#endif -#ifdef MOZ_ENABLE_PANGO - } -#endif - - NS_ADDREF(result); - nsresult rv = result->QueryInterface(aIID, aResult); - NS_RELEASE(result); - - return rv; -} - -static NS_IMETHODIMP nsScriptableRegionConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) -{ - nsresult rv; - - nsIScriptableRegion *inst; - - if ( !aResult ) - { - rv = NS_ERROR_NULL_POINTER; - return rv; - } - *aResult = nsnull; - if (aOuter) - { - rv = NS_ERROR_NO_AGGREGATION; - return rv; - } - // create an nsRegionGtk and get the scriptable region from it - nsCOMPtr rgn; - NS_NEWXPCOM(rgn, nsRegionGTK); - nsCOMPtr scriptableRgn; - if (rgn != nsnull) - { - scriptableRgn = new nsScriptableRegion(rgn); - inst = scriptableRgn; - } - if (!inst) - { - rv = NS_ERROR_OUT_OF_MEMORY; - return rv; - } - NS_ADDREF(inst); - // release our variable above now that we have created our owning - // reference - we don't want this to go out of scope early! - scriptableRgn = nsnull; - rv = inst->QueryInterface(aIID, aResult); - NS_RELEASE(inst); - - return rv; -} - -static const nsModuleComponentInfo components[] = -{ - { "Gtk Font Metrics", - NS_FONT_METRICS_CID, - // "@mozilla.org/gfx/font_metrics/gtk;1", - "@mozilla.org/gfx/fontmetrics;1", - nsFontMetricsConstructor }, - { "Gtk Device Context", - NS_DEVICE_CONTEXT_CID, - // "@mozilla.org/gfx/device_context/gtk;1", - "@mozilla.org/gfx/devicecontext;1", - nsDeviceContextGTKConstructor }, - { "Gtk Rendering Context", - NS_RENDERING_CONTEXT_CID, - // "@mozilla.org/gfx/rendering_context/gtk;1", - "@mozilla.org/gfx/renderingcontext;1", - nsRenderingContextGTKConstructor }, - { "Gtk Image", - NS_IMAGE_CID, - // "@mozilla.org/gfx/image/gtk;1", - "@mozilla.org/gfx/image;1", - nsImageGTKConstructor }, - { "Gtk Region", - NS_REGION_CID, - "@mozilla.org/gfx/region/gtk;1", - nsRegionGTKConstructor }, - { "Scriptable Region", - NS_SCRIPTABLE_REGION_CID, - // "@mozilla.org/gfx/scriptable_region;1", - "@mozilla.org/gfx/region;1", - nsScriptableRegionConstructor }, - { "Blender", - NS_BLENDER_CID, - // "@mozilla.org/gfx/blender;1", - "@mozilla.org/gfx/blender;1", - nsBlenderConstructor }, - { "GTK Font Enumerator", - NS_FONT_ENUMERATOR_CID, - // "@mozilla.org/gfx/font_enumerator/gtk;1", - "@mozilla.org/gfx/fontenumerator;1", - nsFontEnumeratorConstructor }, - { "Font List", - NS_FONTLIST_CID, - // "@mozilla.org/gfx/fontlist;1" - NS_FONTLIST_CONTRACTID, - nsFontListConstructor }, - { "windows image frame", - GFX_IMAGEFRAME_CID, - "@mozilla.org/gfx/image/frame;2", - gfxImageFrameConstructor, }, -#ifdef MOZ_ENABLE_FREETYPE2 - { "TrueType Font Catalog Service", - NS_FONTCATALOGSERVICE_CID, - "@mozilla.org/gfx/xfontcatalogservice;1", - nsFT2FontCatalogConstructor }, - { "FreeType2 routines", - NS_FREETYPE2_CID, - NS_FREETYPE2_CONTRACTID, - nsFreeType2Constructor }, -#endif -}; - -PR_STATIC_CALLBACK(nsresult) -nsGfxGTKModuleCtor(nsIModule *self) -{ - nsImageGTK::Startup(); - return NS_OK; -} - -PR_STATIC_CALLBACK(void) -nsGfxGTKModuleDtor(nsIModule *self) -{ - nsRenderingContextGTK::Shutdown(); - nsDeviceContextGTK::Shutdown(); - nsImageGTK::Shutdown(); - nsGCCache::Shutdown(); -} - -NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(nsGfxGTKModule, components, - nsGfxGTKModuleCtor, nsGfxGTKModuleDtor) diff --git a/gfx/src/gtk/nsGraphicsStateGTK.cpp b/gfx/src/gtk/nsGraphicsStateGTK.cpp deleted file mode 100644 index 3debd91e3697..000000000000 --- a/gfx/src/gtk/nsGraphicsStateGTK.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsGraphicsStateGTK.h" - -////////////////////////////////////////////////////////////////////////// -nsGraphicsState::nsGraphicsState() -{ - mMatrix = nsnull; - mClipRegion = nsnull; - mColor = 0; - mLineStyle = nsLineStyle_kSolid; - mFontMetrics = nsnull; -} -////////////////////////////////////////////////////////////////////////// -nsGraphicsState::~nsGraphicsState() -{ - NS_IF_RELEASE(mFontMetrics); -} -////////////////////////////////////////////////////////////////////////// -nsGraphicsStatePool::nsGraphicsStatePool() -{ - mFreeList = nsnull; -} -////////////////////////////////////////////////////////////////////////// - - - -////////////////////////////////////////////////////////////////////////// -// -// Public nsGraphicsStatePool -// -////////////////////////////////////////////////////////////////////////// -/* static */ nsGraphicsState * -nsGraphicsStatePool::GetNewGS() -{ - nsGraphicsStatePool * thePool = PrivateGetPool(); - - return thePool->PrivateGetNewGS(); -} -////////////////////////////////////////////////////////////////////////// -/* static */ void -nsGraphicsStatePool::ReleaseGS(nsGraphicsState* aGS) -{ - nsGraphicsStatePool * thePool = PrivateGetPool(); - - thePool->PrivateReleaseGS(aGS); -} -////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////////////// -// -// Private nsGraphicsStatePool -// -////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////////////// -nsGraphicsStatePool * -nsGraphicsStatePool::gsThePool = nsnull; - -////////////////////////////////////////////////////////////////////////// -nsGraphicsStatePool * -nsGraphicsStatePool::PrivateGetPool() -{ - if (nsnull == gsThePool) - { - gsThePool = new nsGraphicsStatePool(); - } - - return gsThePool; -} - -////////////////////////////////////////////////////////////////////////// - -nsGraphicsStatePool::~nsGraphicsStatePool() -{ - nsGraphicsState* gs = mFreeList; - while (gs != nsnull) { - nsGraphicsState* next = gs->mNext; - delete gs; - gs = next; - } -} -////////////////////////////////////////////////////////////////////////// -nsGraphicsState * -nsGraphicsStatePool::PrivateGetNewGS() -{ - nsGraphicsState* gs = mFreeList; - if (gs != nsnull) { - mFreeList = gs->mNext; - return gs; - } - return new nsGraphicsState; -} -////////////////////////////////////////////////////////////////////////// -void -nsGraphicsStatePool::PrivateReleaseGS(nsGraphicsState* aGS) -{ - // aGS->Clear(); - aGS->mNext = mFreeList; - mFreeList = aGS; -} -////////////////////////////////////////////////////////////////////////// - diff --git a/gfx/src/gtk/nsGraphicsStateGTK.h b/gfx/src/gtk/nsGraphicsStateGTK.h deleted file mode 100644 index f538dbba1c3c..000000000000 --- a/gfx/src/gtk/nsGraphicsStateGTK.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsGraphicsStateGTK_h___ -#define nsGraphicsStateGTK_h___ - -#include "nsIRenderingContext.h" -#include "nsIFontMetrics.h" -#include "nsTransform2D.h" -#include "nsRegionGTK.h" -#include "nsCOMPtr.h" - -class nsGraphicsState -{ -public: - - nsTransform2D *mMatrix; - nsCOMPtr mClipRegion; - nscolor mColor; - nsLineStyle mLineStyle; - nsIFontMetrics *mFontMetrics; - - nsGraphicsState *mNext; // link into free list of graphics states. - - friend class nsGraphicsStatePool; - -#ifndef USE_GS_POOL - friend class nsRenderingContextGTK; -#endif - -private: - nsGraphicsState(); - ~nsGraphicsState(); -}; - -class nsGraphicsStatePool -{ -public: - - static nsGraphicsState * GetNewGS(); - static void ReleaseGS(nsGraphicsState* aGS); - - nsGraphicsStatePool(); - ~nsGraphicsStatePool(); - -private: - nsGraphicsState* mFreeList; - - static nsGraphicsStatePool * PrivateGetPool(); - nsGraphicsState * PrivateGetNewGS(); - void PrivateReleaseGS(nsGraphicsState* aGS); - - static nsGraphicsStatePool * gsThePool; -}; - -#endif /* nsGraphicsStateGTK_h___ */ diff --git a/gfx/src/gtk/nsIFontMetricsGTK.h b/gfx/src/gtk/nsIFontMetricsGTK.h deleted file mode 100644 index 3499c2e5a945..000000000000 --- a/gfx/src/gtk/nsIFontMetricsGTK.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Christopher Blizzard . - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nsIFontMetricsGTK_h -#define __nsIFontMetricsGTK_h - -#include "nsIFontMetrics.h" -#include "nsIRenderingContext.h" - -#include "nsDrawingSurfaceGTK.h" - -class nsRenderingContextGTK; - -class nsIFontMetricsGTK : public nsIFontMetrics { -public: - // Get the width for this string. aWidth will be updated with the - // width in points, not twips. Callers must convert it if they - // want it in another format. - virtual nsresult GetWidth(const char* aString, PRUint32 aLength, - nscoord& aWidth, - nsRenderingContextGTK *aContext) = 0; - // aCachedOffset will be updated with a new offset. - virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength, - nscoord& aWidth, PRInt32 *aFontID, - nsRenderingContextGTK *aContext) = 0; - - // Get the text dimensions for this string - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext) = 0; - virtual nsresult GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext)=0; - virtual nsresult GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID, - nsRenderingContextGTK *aContext)=0; - - // Draw a string using this font handle on the surface passed in. - virtual nsresult DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface) = 0; - // aCachedOffset will be updated with a new offset. - virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing, - nsRenderingContextGTK *aContext, - nsDrawingSurfaceGTK *aSurface) = 0; - -#ifdef MOZ_MATHML - // These two functions get the bounding metrics for this handle, - // updating the aBoundingMetrics in Points. This means that the - // caller will have to update them to twips before passing it - // back. - virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - nsRenderingContextGTK *aContext) = 0; - // aCachedOffset will be updated with a new offset. - virtual nsresult GetBoundingMetrics(const PRUnichar *aString, - PRUint32 aLength, - nsBoundingMetrics &aBoundingMetrics, - PRInt32 *aFontID, - nsRenderingContextGTK *aContext) = 0; -#endif /* MOZ_MATHML */ - - // Get a GdkFont for this handle, if there is one. This can - // return 0, which means there is no GdkFont associated with this - // particular handle. - virtual GdkFont* GetCurrentGDKFont(void) = 0; - - // Set the direction of the text rendering - virtual nsresult SetRightToLeftText(PRBool aIsRTL) = 0; - virtual PRBool GetRightToLeftText() = 0; - - virtual nsresult GetClusterInfo(const PRUnichar *aText, - PRUint32 aLength, - PRUint8 *aClusterStarts) = 0; - - virtual PRInt32 GetPosition(const PRUnichar *aText, - PRUint32 aLength, - nsPoint aPt) = 0; - - virtual nsresult GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth) = 0; - virtual nsresult GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth) = 0; - virtual PRInt32 GetMaxStringLength() = 0; -}; - -#endif /* __nsIFontMetricsGTK_h */ diff --git a/gfx/src/gtk/nsImageGTK.cpp b/gfx/src/gtk/nsImageGTK.cpp deleted file mode 100644 index 540698f1f77d..000000000000 --- a/gfx/src/gtk/nsImageGTK.cpp +++ /dev/null @@ -1,2299 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Stuart Parmenter - * Tim Rowley - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include -#include - -#include "imgScaler.h" - -#include "nsImageGTK.h" -#include "nsRenderingContextGTK.h" - -#include "nspr.h" - -#define IsFlagSet(a,b) ((a) & (b)) - -#define NS_GET_BIT(rowptr, x) (rowptr[(x)>>3] & (1<<(7-(x)&0x7))) -#define NS_SET_BIT(rowptr, x) (rowptr[(x)>>3] |= (1<<(7-(x)&0x7))) -#define NS_CLEAR_BIT(rowptr, x) (rowptr[(x)>>3] &= ~(1<<(7-(x)&0x7))) - -// Defining this will trace the allocation of images. This includes -// ctor, dtor and update. -// #define TRACE_IMAGE_ALLOCATION - -//#define CHEAP_PERFORMANCE_MEASURMENT 1 - -// Define this to see tiling debug output -// #define DEBUG_TILING - -/* XXX we are simply creating a GC and setting its function to Copy. - we shouldn't be doing this every time this method is called. this creates - way more trips to the server than we should be doing so we are creating a - static one. -*/ -static GdkGC *s1bitGC = nsnull; -static GdkGC *sXbitGC = nsnull; - -/* XFree86 <= 4.3 has a bug in their stipple code (fbgc.c < 1.13) that - prevents us from doing fast tiling. */ -static PRBool sNeedSlowTile = PR_FALSE; - -#ifdef MOZ_WIDGET_GTK2 -NS_IMPL_ISUPPORTS2(nsImageGTK, nsIImage, nsIGdkPixbufImage) -#else -NS_IMPL_ISUPPORTS1(nsImageGTK, nsIImage) -#endif - -//------------------------------------------------------------ - -nsImageGTK::nsImageGTK() - : mImageBits(nsnull) - , mImagePixmap(nsnull) - , mTrueAlphaBits(nsnull) - , mAlphaBits(nsnull) - , mAlphaPixmap(nsnull) - , mAlphaXImage(nsnull) - , mWidth(0) - , mHeight(0) - , mRowBytes(0) - , mSizeImage(0) - , mDecodedX1(PR_INT32_MAX) - , mDecodedY1(PR_INT32_MAX) - , mDecodedX2(0) - , mDecodedY2(0) - , mAlphaDepth(0) - , mTrueAlphaDepth(0) - , mIsSpacer(PR_TRUE) - , mPendingUpdate(PR_FALSE) - , mDepth(0) - , mOptimized(PR_FALSE) -{ -#ifdef TRACE_IMAGE_ALLOCATION - printf("nsImageGTK::nsImageGTK(this=%p)\n", - this); -#endif -} - -//------------------------------------------------------------ - -nsImageGTK::~nsImageGTK() -{ - if(nsnull != mImageBits) { - free(mImageBits); - mImageBits = nsnull; - } - - if (nsnull != mAlphaBits) { - free(mAlphaBits); - mAlphaBits = nsnull; - } - - if (nsnull != mTrueAlphaBits) { - free(mTrueAlphaBits); - mTrueAlphaBits = nsnull; - } - - if (mAlphaPixmap) { - gdk_pixmap_unref(mAlphaPixmap); - } - - if (mImagePixmap) { - gdk_pixmap_unref(mImagePixmap); - } - - if (mAlphaXImage) { - mAlphaXImage->data = 0; - XDestroyImage(mAlphaXImage); - } - -#ifdef TRACE_IMAGE_ALLOCATION - printf("nsImageGTK::~nsImageGTK(this=%p)\n", - this); -#endif -} - -/* static */ void -nsImageGTK::Startup() -{ - Display *dpy = GDK_DISPLAY(); - - if (strstr(ServerVendor(dpy), "XFree86") && VendorRelease(dpy) < 40400000) - sNeedSlowTile = PR_TRUE; -} - -/* static */ void -nsImageGTK::Shutdown() -{ - if (s1bitGC) { - gdk_gc_unref(s1bitGC); - s1bitGC = nsnull; - } - if (sXbitGC) { - gdk_gc_unref(sXbitGC); - sXbitGC = nsnull; - } -} - -//------------------------------------------------------------ - -nsresult nsImageGTK::Init(PRInt32 aWidth, PRInt32 aHeight, - PRInt32 aDepth, nsMaskRequirements aMaskRequirements) -{ - // Assumed: Init only gets called once by gfxIImageFrame - g_return_val_if_fail ((aWidth != 0) || (aHeight != 0), NS_ERROR_FAILURE); - - // X Protocol limits us to image dimensions less than 32767 - // unless we want to go through lots of pain and suffering. - if (aWidth > SHRT_MAX || aHeight > SHRT_MAX) - return NS_ERROR_FAILURE; - - if (24 == aDepth) { - mNumBytesPixel = 3; - } else { - NS_ASSERTION(PR_FALSE, "unexpected image depth"); - return NS_ERROR_UNEXPECTED; - } - - mWidth = aWidth; - mHeight = aHeight; - mDepth = aDepth; - -#ifdef TRACE_IMAGE_ALLOCATION - printf("nsImageGTK::Init(this=%p,%d,%d,%d,%d)\n", - this, - aWidth, - aHeight, - aDepth, - aMaskRequirements); -#endif - - // create the memory for the image - ComputeMetrics(); - - mImageBits = (PRUint8*)malloc(mSizeImage); - if (!mImageBits) - return NS_ERROR_OUT_OF_MEMORY; - - switch(aMaskRequirements) - { - case nsMaskRequirements_kNeeds8Bit: - mTrueAlphaRowBytes = aWidth; - mTrueAlphaDepth = 8; - - // 32-bit align each row - mTrueAlphaRowBytes = (mTrueAlphaRowBytes + 3) & ~0x3; - mTrueAlphaBits = (PRUint8*)calloc(mTrueAlphaRowBytes * aHeight, 1); - if (!mTrueAlphaBits) - return NS_ERROR_OUT_OF_MEMORY; - - // FALL THROUGH - - case nsMaskRequirements_kNeeds1Bit: - mAlphaRowBytes = (aWidth + 7) / 8; - mAlphaDepth = 1; - - // 32-bit align each row - mAlphaRowBytes = (mAlphaRowBytes + 3) & ~0x3; - - mAlphaBits = (PRUint8*)calloc(mAlphaRowBytes * aHeight, 1); - if (!mAlphaBits) - return NS_ERROR_OUT_OF_MEMORY; - break; - - default: - break; // avoid compiler warning - } - - if (aMaskRequirements == nsMaskRequirements_kNeeds8Bit) - mAlphaDepth = 0; - - return NS_OK; -} - -//------------------------------------------------------------ - -PRInt32 nsImageGTK::GetHeight() -{ - return mHeight; -} - -PRInt32 nsImageGTK::GetWidth() -{ - return mWidth; -} - -PRUint8 *nsImageGTK::GetBits() -{ - return mImageBits; -} - -void *nsImageGTK::GetBitInfo() -{ - return nsnull; -} - -PRInt32 nsImageGTK::GetLineStride() -{ - return mRowBytes; -} - -nsColorMap *nsImageGTK::GetColorMap() -{ - return nsnull; -} - -PRUint8 *nsImageGTK::GetAlphaBits() -{ - if (mTrueAlphaBits) - return mTrueAlphaBits; - else - return mAlphaBits; -} - -PRInt32 -nsImageGTK::GetAlphaLineStride() -{ - if (mTrueAlphaBits) - return mTrueAlphaRowBytes; - else - return mAlphaRowBytes; -} - -void nsImageGTK::ImageUpdated(nsIDeviceContext *aContext, - PRUint8 aFlags, - nsRect *aUpdateRect) -{ - mPendingUpdate = PR_TRUE; - mUpdateRegion.Or(mUpdateRegion, *aUpdateRect); - - mDecodedX1 = PR_MIN(mDecodedX1, aUpdateRect->x); - mDecodedY1 = PR_MIN(mDecodedY1, aUpdateRect->y); - - if (aUpdateRect->YMost() > mDecodedY2) - mDecodedY2 = aUpdateRect->YMost(); - if (aUpdateRect->XMost() > mDecodedX2) - mDecodedX2 = aUpdateRect->XMost(); -} - -/** --------------------------------------------------- - * See documentation in nsIImage.h - */ -PRBool nsImageGTK::GetIsImageComplete() { - return mDecodedX1 == 0 && - mDecodedY1 == 0 && - mDecodedX2 == mWidth && - mDecodedY2 == mHeight; -} - -void nsImageGTK::UpdateCachedImage() -{ -#ifdef TRACE_IMAGE_ALLOCATION - printf("nsImageGTK::ImageUpdated(this=%p)\n", - this); -#endif - - nsRegionRectIterator ri(mUpdateRegion); - const nsRect *rect; - - while ((rect = ri.Next()) != nsnull) { - -// fprintf(stderr, "ImageUpdated %p x,y=(%d %d) width,height=(%d %d)\n", -// this, rect->x, rect->y, rect->width, rect->height); - - unsigned bottom, left, right; - bottom = rect->y + rect->height; - left = rect->x; - right = left + rect->width; - - // check if the image has an all-opaque 8-bit alpha mask - if ((mTrueAlphaDepth==8) && (mAlphaDepthy; - (y> (left & 0x7); - PRUint8 rightmask = 0xff << (7 - ((right-1) & 0x7)); - - // byte where the first/last bits of the update region are located - PRUint32 leftindex = left >> 3; - PRUint32 rightindex = (right-1) >> 3; - - // first/last bits in the same byte - combine mask into leftmask - // and fill rightmask so we don't try using it - if (leftindex == rightindex) { - leftmask &= rightmask; - rightmask = 0xff; - } - - // check the leading bits - if (leftmask != 0xff) { - PRUint8 *ptr = mAlphaBits + mAlphaRowBytes * rect->y + leftindex; - for (unsigned y=rect->y; yy + rightindex; - for (unsigned y=rect->y; yy; (yx, rect->y, - rect->width, rect->height, - GDK_RGB_DITHER_MAX, - mImageBits + mRowBytes*rect->y + 3*rect->x, - mRowBytes, - 0, 0); - } - - if (mAlphaDepth==1) { - XPutImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap), - GDK_WINDOW_XWINDOW(mAlphaPixmap), - GDK_GC_XGC(s1bitGC), - mAlphaXImage, - rect->x, rect->y, - rect->x, rect->y, - rect->width, rect->height); - } - } - - mUpdateRegion.SetEmpty(); - mPendingUpdate = PR_FALSE; - mFlags = nsImageUpdateFlags_kBitsChanged; // this should be 0'd out by Draw() -} - -#ifdef CHEAP_PERFORMANCE_MEASURMENT -static PRTime gConvertTime, gAlphaTime, gCopyStart, gCopyEnd, gStartTime, gPixmapTime, gEndTime; -#endif - -/* Xlib image scaling... */ - -#define sign(x) ((x)>0 ? 1:-1) - -static void XlibStretchHorizontal(long x1,long x2,long y1,long y2, - long ymin,long ymax, - long startColumn, long endColumn, - long offsetX, long offsetY, - GdkPixmap *aSrcImage, GdkPixmap *aDstImage, GdkGC *gc); - -/********************************************************** - XlibRectStretch enlarges or diminishes a source rectangle of a bitmap to - a destination rectangle. The source rectangle is selected by the two - points (xs1,ys1) and (xs2,ys2), and the destination rectangle by - (xd1,yd1) and (xd2,yd2). - - Entry: - xs1,ys1 - first point of source rectangle - xs2,ys2 - second point of source rectangle - xd1,yd1 - first point of destination rectangle - xd2,yd2 - second point of destination rectangle - offx, offy - offset to target -**********************************************************/ -void -XlibRectStretch(PRInt32 srcWidth, PRInt32 srcHeight, - PRInt32 dstWidth, PRInt32 dstHeight, - PRInt32 dstOrigX, PRInt32 dstOrigY, - PRInt32 aDX, PRInt32 aDY, - PRInt32 aDWidth, PRInt32 aDHeight, - GdkPixmap *aSrcImage, GdkPixmap *aDstImage, - GdkGC *gc, GdkGC *copygc, PRInt32 aDepth) -{ - long dx,dy,e,d,dx2; - short sx,sy; - GdkPixmap *aTmpImage = 0; - PRBool skipHorizontal=PR_FALSE, skipVertical=PR_FALSE; - long startColumn, startRow, endColumn, endRow; - long xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2; - - xs1 = ys1 = xd1 = yd1 = 0; - xs2 = srcWidth-1; - ys2 = srcHeight-1; - xd2 = dstWidth-1; - yd2 = dstHeight-1; - -// fprintf(stderr, "XRS %p (%ld %ld)-(%ld %ld) (%ld %ld)-(%ld %ld)\n", -// (void *)aDstImage, xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2); - - startColumn = aDX-dstOrigX; - startRow = aDY-dstOrigY; - endColumn = aDX+aDWidth-dstOrigX; - endRow = aDY+aDHeight-dstOrigY; - -// fprintf(stderr, "startXY = %d %d endXY = %d %d %d x %d\n", -// startColumn, startRow, endColumn, endRow, -// endColumn-startColumn, endRow-startRow); - - long scaleStartY, scaleEndY; - scaleStartY = startRow * (ys2-ys1+1) / (yd2-yd1+1); - scaleEndY = 1 + endRow * (ys2-ys1+1) / (yd2-yd1+1); - - if (xd2-xd1 == xs2-xs1) { -// fprintf(stderr, "skipping horizontal\n"); - skipHorizontal = PR_TRUE; - aTmpImage = aSrcImage; - scaleStartY = 0; - scaleEndY = ys2; - } - - if (yd2-yd1 == ys2-ys1) { -// fprintf(stderr, "skipping vertical\n"); - skipVertical = PR_TRUE; - aTmpImage = aDstImage; - } - - if (skipVertical && skipHorizontal) { - gdk_draw_pixmap(aDstImage, gc, aSrcImage, - 0, 0, srcWidth, srcHeight, - dstOrigX, dstOrigY); - return; - } - -// fprintf(stderr, "scaleY Start/End = %d %d\n", scaleStartY, scaleEndY); - - if (!skipHorizontal && !skipVertical) { - aTmpImage = gdk_pixmap_new(nsnull, - endColumn-startColumn, - scaleEndY-scaleStartY, - aDepth); -#ifdef MOZ_WIDGET_GTK2 - if (aDepth != 1) - gdk_drawable_set_colormap(GDK_DRAWABLE(aTmpImage), - gdk_rgb_get_colormap()); -#endif - } - - dx = abs((int)(yd2-yd1)); - dy = abs((int)(ys2-ys1)); - sx = sign(yd2-yd1); - sy = sign(ys2-ys1); - e = dy-dx; - dx2 = dx; - dy += 1; - if (!dx2) dx2=1; - - if (!skipHorizontal) - XlibStretchHorizontal(xd1, xd2, xs1, xs2, scaleStartY, scaleEndY, - startColumn, endColumn, - skipVertical?dstOrigX:-startColumn, skipVertical?dstOrigY:-scaleStartY, - aSrcImage, aTmpImage, (skipVertical?gc:copygc)); - - if (!skipVertical) { - for (d=0; d<=dx; d++) { - if ((yd1 >= startRow) && (yd1 <= endRow)) { - gdk_draw_pixmap(aDstImage, gc, aTmpImage, - (skipHorizontal?startColumn:0), ys1-scaleStartY, - aDX, dstOrigY+yd1, - endColumn-startColumn, 1); - } - while (e>=0) { - ys1 += sy; - e -= dx2; - } - yd1 += sx; - e += dy; - } - } - - if (!skipHorizontal && !skipVertical) - gdk_pixmap_unref(aTmpImage); -} - -/********************************************************** - Stretches a image horizontally by column replication/deletion. - Used by XlibRectStretch. - - Entry: - x1,x2 - x-coordinates of the destination line - y1,y2 - x-coordinates of the source line - ymin - y-coordinate of top of stretch region - ymax - y-coordinate of bottom of stretch region -**********************************************************/ -static void -XlibStretchHorizontal(long x1, long x2, long y1, long y2, - long ymin, long ymax, - long startColumn, long endColumn, - long offsetX, long offsetY, - GdkPixmap *aSrcImage, GdkPixmap *aDstImage, GdkGC *gc) -{ - long dx,dy,e,d,dx2; - short sx,sy; - - dx = abs((int)(x2-x1)); - dy = abs((int)(y2-y1)); - sx = sign(x2-x1); - sy = sign(y2-y1); - e = dy-dx; - dx2 = dx; - dy += 1; - if (!dx2) dx2=1; - for (d=0; d<=dx; d++) { - if ((x1 >= startColumn) && (x1 <= endColumn)) { - gdk_draw_pixmap(aDstImage, gc, aSrcImage, - y1, ymin, x1+offsetX, ymin+offsetY, - 1, ymax-ymin); - } - while (e>=0) { - y1 += sy; - e -= dx2; - } - x1 += sx; - e += dy; - } -} - -#undef sign - - - -// Draw the bitmap, this method has a source and destination coordinates -NS_IMETHODIMP -nsImageGTK::Draw(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface, - PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, - PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight) -{ - g_return_val_if_fail ((aSurface != nsnull), NS_ERROR_FAILURE); - - if (mPendingUpdate) - UpdateCachedImage(); - - if ((mAlphaDepth==1) && mIsSpacer) - return NS_OK; - - if (mDecodedX2 < mDecodedX1 || mDecodedY2 < mDecodedY1) - return NS_OK; - -#ifdef TRACE_IMAGE_ALLOCATION - fprintf(stderr, "nsImageGTK::Draw(%p) s=(%4d %4d %4d %4d) d=(%4d %4d %4d %4d)\n", - this, - aSX, aSY, aSWidth, aSHeight, - aDX, aDY, aDWidth, aDHeight); -#endif - - if (aSWidth <= 0 || aDWidth <= 0 || aSHeight <= 0 || aDHeight <= 0) { - return NS_OK; - } - - // store some values we'll need for scaling... - - PRInt32 srcWidth, srcHeight, dstWidth, dstHeight; - PRInt32 dstOrigX, dstOrigY; - - srcWidth = aSWidth; - srcHeight = aSHeight; - dstWidth = aDWidth; - dstHeight = aDHeight; - dstOrigX = aDX; - dstOrigY = aDY; - - // clip to decode region - PRInt32 j = aSX + aSWidth; - PRInt32 z; - if (j > mDecodedX2) { - z = j - mDecodedX2; - aDWidth -= z*dstWidth/srcWidth; - aSWidth -= z; - } - if (aSX < mDecodedX1) { - aDX += (mDecodedX1 - aSX)*dstWidth/srcWidth; - aSX = mDecodedX1; - } - - j = aSY + aSHeight; - if (j > mDecodedY2) { - z = j - mDecodedY2; - aDHeight -= z*dstHeight/srcHeight; - aSHeight -= z; - } - if (aSY < mDecodedY1) { - aDY += (mDecodedY1 - aSY)*dstHeight/srcHeight; - aSY = mDecodedY1; - } - - if (aDWidth <= 0 || aDHeight <= 0 || aSWidth <= 0 || aSHeight <= 0) { - return NS_OK; - } - - // clip to drawing surface - nsDrawingSurfaceGTK *drawing = (nsDrawingSurfaceGTK*)aSurface; - PRUint32 surfaceWidth, surfaceHeight; - drawing->GetDimensions(&surfaceWidth, &surfaceHeight); - - if (aDX + aDWidth > (PRInt32)surfaceWidth) { - z = aDX + aDWidth - surfaceWidth; - aDWidth -= z; - aSWidth -= z*srcWidth/dstWidth; - } - - if (aDX < 0) { - aDWidth += aDX; - aSWidth += aDX*srcWidth/dstWidth; - aSX -= aDX*srcWidth/dstWidth; - aDX = 0; - } - - if (aDY + aDHeight > (PRInt32)surfaceHeight) { - z = aDY + aDHeight - surfaceHeight; - aDHeight -= z; - aSHeight -= z*srcHeight/dstHeight; - } - - if (aDY < 0) { - aDHeight += aDY; - aSHeight += aDY*srcHeight/dstHeight; - aSY -= aDY*srcHeight/dstHeight; - aDY = 0; - } - - if (aDWidth <= 0 || aDHeight <= 0 || aSWidth <= 0 || aSHeight <= 0) { - return NS_OK; - } - - if ((srcWidth != dstWidth) || (srcHeight != dstHeight)) { - GdkPixmap *pixmap = 0; - GdkGC *gc = 0; - nsRegionGTK clipRgn; - - switch (mAlphaDepth) { - case 8: - DrawComposited(aContext, aSurface, - srcWidth, srcHeight, - dstWidth, dstHeight, - dstOrigX, dstOrigY, - aDX, aDY, - aDWidth, aDHeight); - break; - case 1: - pixmap = gdk_pixmap_new(nsnull, dstWidth, dstHeight, 1); - if (pixmap) { - XlibRectStretch(srcWidth, srcHeight, - dstWidth, dstHeight, - 0, 0, - 0, 0, - dstWidth, dstHeight, - mAlphaPixmap, pixmap, - s1bitGC, s1bitGC, 1); - gc = gdk_gc_new(drawing->GetDrawable()); - if (gc) { - gdk_gc_set_clip_origin(gc, dstOrigX, dstOrigY); - gdk_gc_set_clip_mask(gc, pixmap); - } - } - - if (gdk_rgb_get_visual()->depth <= 8) { - PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*dstWidth*dstHeight); - - if (!scaledRGB) - return NS_ERROR_OUT_OF_MEMORY; - - RectStretch(mWidth, mHeight, - dstWidth, dstHeight, - 0, 0, dstWidth-1, dstHeight-1, - mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24); - - if (NS_SUCCEEDED(((nsRenderingContextGTK&)aContext).CopyClipRegion(clipRgn))) { - // we have both a set of rectangles and a bitmap defining the clip - // let X11 clip to the bitmap, do the rectangles by hand - nsRegionRectSet *rectSet = nsnull; - clipRgn.Intersect(aDX, aDY, aDWidth, aDHeight); - clipRgn.GetRects(&rectSet); - for (PRUint32 i=0; imRectsLen; i++) { - nsRegionRect *rect = &(rectSet->mRects[i]); - - gdk_draw_rgb_image_dithalign(drawing->GetDrawable(), gc, - rect->x, rect->y, rect->width, rect->height, - GDK_RGB_DITHER_MAX, - scaledRGB + 3*((rect->y-dstOrigY)*dstWidth+(rect->x-dstOrigX)), - 3*dstWidth, - (rect->x-dstOrigX), (rect->y-dstOrigY)); - } - clipRgn.FreeRects(rectSet); - } else { - gdk_draw_rgb_image_dithalign(drawing->GetDrawable(), gc, - aDX, aDY, aDWidth, aDHeight, - GDK_RGB_DITHER_MAX, - scaledRGB + 3*((aDY-dstOrigY)*dstWidth+(aDX-dstOrigX)), - 3*dstWidth, - (aDX-dstOrigX), (aDY-dstOrigY)); - } - nsMemory::Free(scaledRGB); - } else { - if (NS_SUCCEEDED(((nsRenderingContextGTK&)aContext).CopyClipRegion(clipRgn))) { - // we have both a set of rectangles and a bitmap defining the clip - // let X11 clip to the bitmap, do the rectangles by hand - nsRegionRectSet *rectSet = nsnull; - clipRgn.Intersect(aDX, aDY, aDWidth, aDHeight); - clipRgn.GetRects(&rectSet); - for (PRUint32 i=0; imRectsLen; i++) { - nsRegionRect *rect = &(rectSet->mRects[i]); - - XlibRectStretch(srcWidth, srcHeight, - dstWidth, dstHeight, - dstOrigX, dstOrigY, - rect->x, rect->y, - rect->width, rect->height, - mImagePixmap, drawing->GetDrawable(), - gc, sXbitGC, gdk_rgb_get_visual()->depth); - } - clipRgn.FreeRects(rectSet); - } else { - // only a mask - XlibRectStretch(srcWidth, srcHeight, - dstWidth, dstHeight, - dstOrigX, dstOrigY, - aDX, aDY, - aDWidth, aDHeight, - mImagePixmap, drawing->GetDrawable(), - gc, sXbitGC, gdk_rgb_get_visual()->depth); - } - } - - break; - case 0: - if (!gc) - gc = ((nsRenderingContextGTK&)aContext).GetGC(); - - if (gdk_rgb_get_visual()->depth <= 8) { - PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*dstWidth*dstHeight); - if (!scaledRGB) - break; - RectStretch(mWidth, mHeight, - dstWidth, dstHeight, - 0, 0, dstWidth-1, dstHeight-1, - mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24); - - gdk_draw_rgb_image_dithalign(drawing->GetDrawable(), gc, - aDX, aDY, aDWidth, aDHeight, - GDK_RGB_DITHER_MAX, - scaledRGB + 3*((aDY-dstOrigY)*dstWidth+(aDX-dstOrigX)), - 3*dstWidth, - (aDX-dstOrigX), (aDY-dstOrigY)); - - nsMemory::Free(scaledRGB); - } - else - XlibRectStretch(srcWidth, srcHeight, - dstWidth, dstHeight, - dstOrigX, dstOrigY, - aDX, aDY, - aDWidth, aDHeight, - mImagePixmap, drawing->GetDrawable(), - gc, sXbitGC, gdk_rgb_get_visual()->depth); - break; - } - if (gc) - gdk_gc_unref(gc); - if (pixmap) - gdk_pixmap_unref(pixmap); - - mFlags = 0; - return NS_OK; - } - - // now start drawing... - - if (mAlphaDepth==8) { - DrawComposited(aContext, aSurface, - srcWidth, srcHeight, - dstWidth, dstHeight, - aDX-aSX, aDY-aSY, - aDX, aDY, - aDWidth, aDHeight); - return NS_OK; - } - - GdkGC *copyGC; - if (mAlphaPixmap) { - copyGC = gdk_gc_new(drawing->GetDrawable()); - GdkGC *gc = ((nsRenderingContextGTK&)aContext).GetGC(); - gdk_gc_copy(copyGC, gc); - gdk_gc_unref(gc); // unref the one we got - - SetupGCForAlpha(copyGC, aDX-aSX, aDY-aSY); - } else { - // don't make a copy... we promise not to change it - copyGC = ((nsRenderingContextGTK&)aContext).GetGC(); - } - - nsRegionGTK clipRgn; - if (mAlphaPixmap && - NS_SUCCEEDED(((nsRenderingContextGTK&)aContext).CopyClipRegion(clipRgn))) { - // we have both a set of rectangles and a bitmap defining the clip - // let X11 clip to the bitmap, do the rectangles by hand - nsRegionRectSet *rectSet = nsnull; - clipRgn.Intersect(aDX, aDY, aSWidth, aSHeight); - clipRgn.GetRects(&rectSet); - for (PRUint32 i=0; imRectsLen; i++) { - nsRegionRect *rect = &(rectSet->mRects[i]); - gdk_window_copy_area(drawing->GetDrawable(), // dest window - copyGC, // gc - rect->x, // xdest - rect->y, // ydest - mImagePixmap, // source window - aSX+(rect->x-aDX), // xsrc - aSY+(rect->y-aDY), // ysrc - rect->width, // width - rect->height); // height - } - clipRgn.FreeRects(rectSet); - } else { - // normal case - let X11 take care of all the clipping - gdk_window_copy_area(drawing->GetDrawable(), // dest window - copyGC, // gc - aDX, // xdest - aDY, // ydest - mImagePixmap, // source window - aSX, // xsrc - aSY, // ysrc - aSWidth, // width - aSHeight); // height - } - - gdk_gc_unref(copyGC); - mFlags = 0; - - return NS_OK; -} - -//------------------------------------------------------------ -// 8-bit alpha composite drawing... -// Most of this will disappear with gtk+-1.4 - -// Compositing code consists of these functions: -// * findIndex32() - helper function to convert mask into bitshift offset -// * findIndex24() - helper function to convert mask into bitshift offset -// * nsImageGTK::DrawComposited32() - 32-bit (888) truecolor convert/composite -// * nsImageGTK::DrawComposited24() - 24-bit (888) truecolor convert/composite -// * nsImageGTK::DrawComposited16() - 16-bit ([56][56][56]) truecolor -// convert/composite -// * nsImageGTK::DrawCompositedGeneral() - convert/composite for any visual -// not handled by the above methods -// * nsImageGTK::DrawComposited() - compositing master method; does region -// clipping, calls one of the above, then -// writes out the composited image - -static unsigned -findIndex32(unsigned mask) -{ - switch (mask) { - case 0xff: - return 3; - case 0xff00: - return 2; - case 0xff0000: - return 1; - case 0xff000000: - return 0; - default: - return 0; - } -} - -static unsigned -findIndex24(unsigned mask) -{ - switch (mask) { - case 0xff: - return 2; - case 0xff00: - return 1; - case 0xff0000: - return 0; - default: - return 0; - } -} - - -// 32-bit (888) truecolor convert/composite function -void -nsImageGTK::DrawComposited32(PRBool isLSB, PRBool flipBytes, - PRUint8 *imageOrigin, PRUint32 imageStride, - PRUint8 *alphaOrigin, PRUint32 alphaStride, - unsigned width, unsigned height, - XImage *ximage, unsigned char *readData, unsigned char *srcData) -{ - GdkVisual *visual = gdk_rgb_get_visual(); - unsigned redIndex = findIndex32(visual->red_mask); - unsigned greenIndex = findIndex32(visual->green_mask); - unsigned blueIndex = findIndex32(visual->blue_mask); - - if (flipBytes^isLSB) { - redIndex = 3-redIndex; - greenIndex = 3-greenIndex; - blueIndex = 3-blueIndex; - } - -// fprintf(stderr, "startX=%u startY=%u activeX=%u activeY=%u\n", -// startX, startY, activeX, activeY); -// fprintf(stderr, "width=%u height=%u\n", ximage->width, ximage->height); - - for (unsigned y=0; ybytes_per_line; - unsigned char *targetRow = readData + 3*(y*ximage->width); - unsigned char *imageRow = imageOrigin + y*imageStride; - unsigned char *alphaRow = alphaOrigin + y*alphaStride; - - for (unsigned i=0; ired_mask); - unsigned greenIndex = findIndex24(visual->green_mask); - unsigned blueIndex = findIndex24(visual->blue_mask); - - if (flipBytes^isLSB) { - redIndex = 2-redIndex; - greenIndex = 2-greenIndex; - blueIndex = 2-blueIndex; - } - - for (unsigned y=0; ybytes_per_line; - unsigned char *targetRow = readData + 3*(y*ximage->width); - unsigned char *imageRow = imageOrigin + y*imageStride; - unsigned char *alphaRow = alphaOrigin + y*alphaStride; - - for (unsigned i=0; ired_prec == 5) ? scaled5 : scaled6; - unsigned *greenScale = (visual->green_prec == 5) ? scaled5 : scaled6; - unsigned *blueScale = (visual->blue_prec == 5) ? scaled5 : scaled6; - - for (unsigned y=0; ybytes_per_line; - unsigned char *targetRow = readData + 3*(y*ximage->width); - unsigned char *imageRow = imageOrigin + y*imageStride; - unsigned char *alphaRow = alphaOrigin + y*alphaStride; - - for (unsigned i=0; ired_mask)>>visual->red_shift], - imageRow[0], alpha); - MOZ_BLEND(targetRow[1], - greenScale[(pix&visual->green_mask)>>visual->green_shift], - imageRow[1], alpha); - MOZ_BLEND(targetRow[2], - blueScale[(pix&visual->blue_mask)>>visual->blue_shift], - imageRow[2], alpha); - } - } -} - -// Generic convert/composite function -void -nsImageGTK::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes, - PRUint8 *imageOrigin, PRUint32 imageStride, - PRUint8 *alphaOrigin, PRUint32 alphaStride, - unsigned width, unsigned height, - XImage *ximage, unsigned char *readData, unsigned char *srcData) -{ - GdkVisual *visual = gdk_rgb_get_visual(); - GdkColormap *colormap = gdk_rgb_get_cmap(); - - // flip bytes - if (flipBytes && (ximage->bits_per_pixel>=16)) { - for (int row=0; rowheight; row++) { - unsigned char *ptr = srcData + row*ximage->bytes_per_line; - if (ximage->bits_per_pixel==24) { // Aurgh.... - for (int col=0; - colbytes_per_line; - col+=(ximage->bits_per_pixel/8)) { - unsigned char tmp; - tmp = *ptr; - *ptr = *(ptr+2); - *(ptr+2) = tmp; - ptr+=3; - } - continue; - } - - for (int col=0; - colbytes_per_line; - col+=(ximage->bits_per_pixel/8)) { - unsigned char tmp; - switch (ximage->bits_per_pixel) { - case 16: - tmp = *ptr; - *ptr = *(ptr+1); - *(ptr+1) = tmp; - ptr+=2; - break; - case 32: - tmp = *ptr; - *ptr = *(ptr+3); - *(ptr+3) = tmp; - tmp = *(ptr+1); - *(ptr+1) = *(ptr+2); - *(ptr+2) = tmp; - ptr+=4; - break; - } - } - } - } - - unsigned redScale, greenScale, blueScale, redFill, greenFill, blueFill; - redScale = 8-visual->red_prec; - greenScale = 8-visual->green_prec; - blueScale = 8-visual->blue_prec; - redFill = 0xff>>visual->red_prec; - greenFill = 0xff>>visual->green_prec; - blueFill = 0xff>>visual->blue_prec; - - for (unsigned row=0; rowbytes_per_line; - unsigned char *target = readData+3*row*ximage->width; - for (unsigned col=0; colbits_per_pixel) { - case 1: - pix = (*ptr>>(col%8))&1; - if ((col%8)==7) - ptr++; - break; - case 4: - pix = (col&1)?(*ptr>>4):(*ptr&0xf); - if (col&1) - ptr++; - break; - case 8: - pix = *ptr++; - break; - case 16: - pix = *((short *)ptr); - ptr+=2; - break; - case 24: - if (isLSB) - pix = (*(ptr+2)<<16) | (*(ptr+1)<<8) | *ptr; - else - pix = (*ptr<<16) | (*(ptr+1)<<8) | *(ptr+2); - ptr+=3; - break; - case 32: - pix = *((unsigned *)ptr); - ptr+=4; - break; - } - switch (visual->type) { - case GDK_VISUAL_STATIC_GRAY: - case GDK_VISUAL_GRAYSCALE: - case GDK_VISUAL_STATIC_COLOR: - case GDK_VISUAL_PSEUDO_COLOR: - *target++ = colormap->colors[pix].red >>8; - *target++ = colormap->colors[pix].green >>8; - *target++ = colormap->colors[pix].blue >>8; - break; - - case GDK_VISUAL_DIRECT_COLOR: - *target++ = - colormap->colors[(pix&visual->red_mask)>>visual->red_shift].red >> 8; - *target++ = - colormap->colors[(pix&visual->green_mask)>>visual->green_shift].green >> 8; - *target++ = - colormap->colors[(pix&visual->blue_mask)>>visual->blue_shift].blue >> 8; - break; - - case GDK_VISUAL_TRUE_COLOR: - *target++ = - redFill|((pix&visual->red_mask)>>visual->red_shift)<green_mask)>>visual->green_shift)<blue_mask)>>visual->blue_shift)<width; - unsigned char *imageRow = imageOrigin + y*imageStride; - unsigned char *alphaRow = alphaOrigin + y*alphaStride; - - for (unsigned i=0; iGetDrawable()); - Drawable drawable = GDK_WINDOW_XWINDOW(drawing->GetDrawable()); - - int readX, readY; - unsigned readWidth, readHeight, destX, destY; - - destX = aDX-dstOrigX; - destY = aDY-dstOrigY; - readX = aDX; - readY = aDY; - readWidth = aDWidth; - readHeight = aDHeight; - -// fprintf(stderr, "dstOrigX=%d dstOrigY=%d, dstWidth=%u dstHeight=%u\n", dstOrigX, dstOrigY, dstWidth, dstHeight); -// fprintf(stderr, "srcWidth=%u srcHeight=%u\n", srcWidth, srcHeight); -// fprintf(stderr, "readX=%u readY=%u readWidth=%u readHeight=%u destX=%u destY=%u\n\n", -// readX, readY, readWidth, readHeight, destX, destY); - - XImage *ximage = XGetImage(dpy, drawable, - readX, readY, readWidth, readHeight, - AllPlanes, ZPixmap); - - NS_ASSERTION((ximage!=NULL), "XGetImage() failed"); - if (!ximage) - return; - - unsigned char *readData = - (unsigned char *)nsMemory::Alloc(3*readWidth*readHeight); - if (!readData) { - XDestroyImage(ximage); - return; - } - - PRUint8 *scaledImage = 0; - PRUint8 *scaledAlpha = 0; - PRUint8 *imageOrigin, *alphaOrigin; - PRUint32 imageStride, alphaStride; - if ((srcWidth!=dstWidth) || (srcHeight!=dstHeight)) { - PRUint32 x1, y1, x2, y2; - x1 = destX*srcWidth/dstWidth; - y1 = destY*srcHeight/dstHeight; - x2 = (destX+aDWidth)*srcWidth/dstWidth; - y2 = (destY+aDHeight)*srcHeight/dstHeight; - - scaledImage = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight); - scaledAlpha = (PRUint8 *)nsMemory::Alloc(aDWidth*aDHeight); - if (!scaledImage || !scaledAlpha) { - XDestroyImage(ximage); - nsMemory::Free(readData); - if (scaledImage) - nsMemory::Free(scaledImage); - if (scaledAlpha) - nsMemory::Free(scaledAlpha); - return; - } - RectStretch(srcWidth, srcHeight, - dstWidth, dstHeight, - destX, destY, - destX+aDWidth-1, destY+aDHeight-1, - mImageBits, mRowBytes, scaledImage, 3*readWidth, 24); - RectStretch(srcWidth, srcHeight, - dstWidth, dstHeight, - destX, destY, - destX+aDWidth-1, destY+aDHeight-1, - mAlphaBits, mAlphaRowBytes, scaledAlpha, readWidth, 8); - imageOrigin = scaledImage; - imageStride = 3*readWidth; - alphaOrigin = scaledAlpha; - alphaStride = readWidth; - } else { - imageOrigin = mImageBits + destY*mRowBytes + 3*destX; - imageStride = mRowBytes; - alphaOrigin = mAlphaBits + destY*mAlphaRowBytes + destX; - alphaStride = mAlphaRowBytes; - } - - PRBool isLSB; - unsigned test = 1; - isLSB = (((char *)&test)[0]) ? 1 : 0; - - PRBool flipBytes = - ( isLSB && ximage->byte_order != LSBFirst) || - (!isLSB && ximage->byte_order == LSBFirst); - - if ((ximage->bits_per_pixel==32) && - (visual->red_prec == 8) && - (visual->green_prec == 8) && - (visual->blue_prec == 8)) - DrawComposited32(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data); - else if ((ximage->bits_per_pixel==24) && - (visual->red_prec == 8) && - (visual->green_prec == 8) && - (visual->blue_prec == 8)) - DrawComposited24(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data); - else if ((ximage->bits_per_pixel==16) && - ((visual->red_prec == 5) || (visual->red_prec == 6)) && - ((visual->green_prec == 5) || (visual->green_prec == 6)) && - ((visual->blue_prec == 5) || (visual->blue_prec == 6))) - DrawComposited16(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data); - else - DrawCompositedGeneral(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data); - - GdkGC *imageGC = ((nsRenderingContextGTK&)aContext).GetGC(); - gdk_draw_rgb_image(drawing->GetDrawable(), imageGC, - readX, readY, readWidth, readHeight, - GDK_RGB_DITHER_MAX, - readData, 3*readWidth); - gdk_gc_unref(imageGC); - - XDestroyImage(ximage); - nsMemory::Free(readData); - if (scaledImage) - nsMemory::Free(scaledImage); - if (scaledAlpha) - nsMemory::Free(scaledAlpha); - mFlags = 0; -} - - -void -nsImageGTK::DrawCompositeTile(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 aSX, PRInt32 aSY, - PRInt32 aSWidth, PRInt32 aSHeight, - PRInt32 aDX, PRInt32 aDY, - PRInt32 aDWidth, PRInt32 aDHeight) -{ - if ((aDWidth==0) || (aDHeight==0)) - return; - - nsDrawingSurfaceGTK* drawing = (nsDrawingSurfaceGTK*) aSurface; - GdkVisual *visual = gdk_rgb_get_visual(); - - Display *dpy = GDK_WINDOW_XDISPLAY(drawing->GetDrawable()); - Drawable drawable = GDK_WINDOW_XWINDOW(drawing->GetDrawable()); - - // I hate clipping... - PRUint32 surfaceWidth, surfaceHeight; - drawing->GetDimensions(&surfaceWidth, &surfaceHeight); - - int readX, readY; - unsigned readWidth, readHeight; - PRInt32 destX, destY; - - if ((aDY>=(int)surfaceHeight) || (aDX>=(int)surfaceWidth) || - (aDY+aDHeight<=0) || (aDX+aDWidth<=0)) { - // This should never happen if the layout engine is sane, - // as it means we're trying to draw an image which is outside - // the drawing surface. Bulletproof gfx for now... - return; - } - - if (aDX<0) { - readX = 0; readWidth = aDWidth+aDX; destX = aSX-aDX; - } else { - readX = aDX; readWidth = aDWidth; destX = aSX; - } - if (aDY<0) { - readY = 0; readHeight = aDHeight+aDY; destY = aSY-aDY; - } else { - readY = aDY; readHeight = aDHeight; destY = aSY; - } - - if (readX+readWidth > surfaceWidth) - readWidth = surfaceWidth-readX; - if (readY+readHeight > surfaceHeight) - readHeight = surfaceHeight-readY; - - if ((readHeight <= 0) || (readWidth <= 0)) - return; - - XImage *ximage = XGetImage(dpy, drawable, - readX, readY, readWidth, readHeight, - AllPlanes, ZPixmap); - - NS_ASSERTION((ximage!=NULL), "XGetImage() failed"); - if (!ximage) - return; - - unsigned char *readData = - (unsigned char *)nsMemory::Alloc(3*readWidth*readHeight); - if (!readData) { - XDestroyImage(ximage); - return; - } - - PRBool isLSB; - unsigned test = 1; - isLSB = (((char *)&test)[0]) ? 1 : 0; - - PRBool flipBytes = - ( isLSB && ximage->byte_order != LSBFirst) || - (!isLSB && ximage->byte_order == LSBFirst); - - - PRUint8 *imageOrigin, *alphaOrigin; - PRUint32 imageStride, alphaStride; - PRUint32 compX, compY; - PRUint8 *compTarget, *compSource; - - imageStride = mRowBytes; - alphaStride = mAlphaRowBytes; - - if (destX==mWidth) - destX = 0; - if (destY==mHeight) - destY = 0; - - for (unsigned y=0; ywidth; - compSource = (unsigned char *)ximage->data + y*ximage->bytes_per_line; - - for (unsigned x=0; xbits_per_pixel==32) && - (visual->red_prec == 8) && - (visual->green_prec == 8) && - (visual->blue_prec == 8)) - DrawComposited32(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - compX, compY, ximage, compTarget, compSource); - else if ((ximage->bits_per_pixel==24) && - (visual->red_prec == 8) && - (visual->green_prec == 8) && - (visual->blue_prec == 8)) - DrawComposited24(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - compX, compY, ximage, compTarget, compSource); - else if ((ximage->bits_per_pixel==16) && - ((visual->red_prec == 5) || (visual->red_prec == 6)) && - ((visual->green_prec == 5) || (visual->green_prec == 6)) && - ((visual->blue_prec == 5) || (visual->blue_prec == 6))) - DrawComposited16(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - compX, compY, ximage, compTarget, compSource); - else - DrawCompositedGeneral(isLSB, flipBytes, - imageOrigin, imageStride, - alphaOrigin, alphaStride, - compX, compY, ximage, compTarget, compSource); - - compTarget += 3*compX; - compSource += (ximage->bits_per_pixel*compX)/8; - } - } - - GdkGC *imageGC = ((nsRenderingContextGTK&)aContext).GetGC(); - gdk_draw_rgb_image(drawing->GetDrawable(), imageGC, - readX, readY, readWidth, readHeight, - GDK_RGB_DITHER_MAX, - readData, 3*readWidth); - gdk_gc_unref(imageGC); - - XDestroyImage(ximage); - nsMemory::Free(readData); - mFlags = 0; -} - - -void nsImageGTK::CreateOffscreenPixmap(PRInt32 aWidth, PRInt32 aHeight) -{ - // Render unique image bits onto an off screen pixmap only once - // The image bits can change as a result of ImageUpdated() - for - // example: animated GIFs. - if (!mImagePixmap) { -#ifdef TRACE_IMAGE_ALLOCATION - printf("nsImageGTK::Draw(this=%p) gdk_pixmap_new(nsnull,width=%d,height=%d,depth=%d)\n", - this, - aWidth, aHeight, - mDepth); -#endif - - // Create an off screen pixmap to hold the image bits. - mImagePixmap = gdk_pixmap_new(nsnull, aWidth, aHeight, - gdk_rgb_get_visual()->depth); -#ifdef MOZ_WIDGET_GTK2 - gdk_drawable_set_colormap(GDK_DRAWABLE(mImagePixmap), gdk_rgb_get_colormap()); -#endif - } - - // Ditto for the clipmask - if ((!mAlphaPixmap) && (mAlphaDepth==1)) { - mAlphaPixmap = gdk_pixmap_new(nsnull, aWidth, aHeight, 1); - - // Need an XImage for clipmask updates (XPutImage) - mAlphaXImage = XCreateImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap), - GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()), - 1, /* visual depth...1 for bitmaps */ - XYPixmap, - 0, /* x offset, XXX fix this */ - (char *)mAlphaBits, /* cast away our sign. */ - aWidth, - aHeight, - 32,/* bitmap pad */ - mAlphaRowBytes); /* bytes per line */ - - mAlphaXImage->bits_per_pixel=1; - - /* Image library always places pixels left-to-right MSB to LSB */ - mAlphaXImage->bitmap_bit_order = MSBFirst; - - /* This definition doesn't depend on client byte ordering - because the image library ensures that the bytes in - bitmask data are arranged left to right on the screen, - low to high address in memory. */ - mAlphaXImage->byte_order = MSBFirst; - - if (!s1bitGC) { - GdkColor fg = { 1, 0, 0, 0 }; - s1bitGC = gdk_gc_new(mAlphaPixmap); - gdk_gc_set_foreground(s1bitGC, &fg); - } - } - - if (!sXbitGC) - sXbitGC = gdk_gc_new(mImagePixmap); -} - - -void nsImageGTK::SetupGCForAlpha(GdkGC *aGC, PRInt32 aX, PRInt32 aY) -{ - // XXX should use (different?) GC cache here - if (mAlphaPixmap) { - // Setup gc to use the given alpha-pixmap for clipping - XGCValues xvalues; - memset(&xvalues, 0, sizeof(XGCValues)); - unsigned long xvalues_mask = 0; - xvalues.clip_x_origin = aX; - xvalues.clip_y_origin = aY; - xvalues_mask = GCClipXOrigin | GCClipYOrigin; - - xvalues.clip_mask = GDK_WINDOW_XWINDOW(mAlphaPixmap); - xvalues_mask |= GCClipMask; - - XChangeGC(GDK_DISPLAY(), GDK_GC_XGC(aGC), xvalues_mask, &xvalues); - } -} - -// Draw the bitmap, this draw just has destination coordinates -NS_IMETHODIMP -nsImageGTK::Draw(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 aX, PRInt32 aY, - PRInt32 aWidth, PRInt32 aHeight) -{ -#ifdef TRACE_IMAGE_ALLOCATION - printf("nsImageGTK::Draw(this=%p,x=%d,y=%d,width=%d,height=%d)\n", - this, - aX, aY, - aWidth, aHeight); -#endif - - return Draw(aContext, aSurface, - 0, 0, mWidth, mHeight, - aX, aY, mWidth, mHeight); -} - -/* inline */ -void nsImageGTK::TilePixmap(GdkPixmap *src, GdkPixmap *dest, - PRInt32 aSXOffset, PRInt32 aSYOffset, - const nsRect &destRect, - const nsRect &clipRect, PRBool aHaveClip) -{ - GdkGC *gc; - GdkGCValues values; - GdkGCValuesMask valuesMask; - memset(&values, 0, sizeof(GdkGCValues)); - values.fill = GDK_TILED; - values.tile = src; - values.ts_x_origin = destRect.x - aSXOffset; - values.ts_y_origin = destRect.y - aSYOffset; - valuesMask = GdkGCValuesMask(GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN); - gc = gdk_gc_new_with_values(src, &values, valuesMask); - - if (aHaveClip) { - GdkRectangle gdkrect = {clipRect.x, clipRect.y, clipRect.width, clipRect.height}; - gdk_gc_set_clip_rectangle(gc, &gdkrect); - } - - // draw to destination window - #ifdef DEBUG_TILING - printf("nsImageGTK::TilePixmap(..., %d, %d, %d, %d)\n", - destRect.x, destRect.y, - destRect.width, destRect.height); - #endif - - gdk_draw_rectangle(dest, gc, PR_TRUE, - destRect.x, destRect.y, - destRect.width, destRect.height); - - gdk_gc_unref(gc); -} - -void nsImageGTK::SlowTile(nsDrawingSurfaceGTK *aSurface, - const nsRect &aTileRect, - PRInt32 aSXOffset, PRInt32 aSYOffset, - const nsRect& aClipRect, PRBool aHaveClip) -{ - GdkPixmap *tileImg; - GdkPixmap *tileMask; - - nsRect tmpRect(0,0,aTileRect.width, aTileRect.height); - - tileImg = gdk_pixmap_new(nsnull, aTileRect.width, - aTileRect.height, aSurface->GetDepth()); -#ifdef MOZ_WIDGET_GTK2 - gdk_drawable_set_colormap(GDK_DRAWABLE(tileImg), gdk_rgb_get_colormap()); -#endif - - TilePixmap(mImagePixmap, tileImg, aSXOffset, aSYOffset, tmpRect, - tmpRect, PR_FALSE); - - // tile alpha mask - tileMask = gdk_pixmap_new(nsnull, aTileRect.width, aTileRect.height, - mAlphaDepth); - TilePixmap(mAlphaPixmap, tileMask, aSXOffset, aSYOffset, tmpRect, - tmpRect, PR_FALSE); - - GdkGC *fgc = gdk_gc_new(aSurface->GetDrawable()); - gdk_gc_set_clip_mask(fgc, (GdkBitmap*)tileMask); - gdk_gc_set_clip_origin(fgc, aTileRect.x, aTileRect.y); - - nsRect drawRect = aTileRect; - if (aHaveClip) { - drawRect.IntersectRect(drawRect, aClipRect); - } - - // and copy it back - gdk_window_copy_area(aSurface->GetDrawable(), fgc, drawRect.x, - drawRect.y, tileImg, - drawRect.x - aTileRect.x, drawRect.y - aTileRect.y, - drawRect.width, drawRect.height); - gdk_gc_unref(fgc); - - gdk_pixmap_unref(tileImg); - gdk_pixmap_unref(tileMask); -} - - -NS_IMETHODIMP nsImageGTK::DrawTile(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 aSXOffset, PRInt32 aSYOffset, - PRInt32 aPadX, PRInt32 aPadY, - const nsRect &aTileRect) -{ -#ifdef DEBUG_TILING - printf("nsImageGTK::DrawTile: mWidth=%d, mHeight=%d\n", mWidth, mHeight); - printf("nsImageGTK::DrawTile((src: %d, %d), (tile: %d,%d, %d, %d) %p\n", aSXOffset, aSYOffset, - aTileRect.x, aTileRect.y, - aTileRect.width, aTileRect.height, this); -#endif - if (mPendingUpdate) - UpdateCachedImage(); - - if ((mAlphaDepth==1) && mIsSpacer) - return NS_OK; - - if (mDecodedX2 < mDecodedX1 || mDecodedY2 < mDecodedY1) - return NS_OK; - - nsDrawingSurfaceGTK *drawing = (nsDrawingSurfaceGTK*)aSurface; - PRBool partial = PR_FALSE; - - PRInt32 - validX = 0, - validY = 0, - validWidth = mWidth, - validHeight = mHeight; - - // limit the image rectangle to the size of the image data which - // has been validated. - if (mDecodedY2 < mHeight) { - validHeight = mDecodedY2 - mDecodedY1; - partial = PR_TRUE; - } - if (mDecodedX2 < mWidth) { - validWidth = mDecodedX2 - mDecodedX1; - partial = PR_TRUE; - } - if (mDecodedY1 > 0) { - validHeight -= mDecodedY1; - validY = mDecodedY1; - partial = PR_TRUE; - } - if (mDecodedX1 > 0) { - validWidth -= mDecodedX1; - validX = mDecodedX1; - partial = PR_TRUE; - } - - if (aTileRect.width == 0 || aTileRect.height == 0 || - validWidth == 0 || validHeight == 0) { - return NS_OK; - } - - if (partial || (mAlphaDepth == 8) || (aPadX || aPadY)) { - PRInt32 aY0 = aTileRect.y - aSYOffset, - aX0 = aTileRect.x - aSXOffset, - aY1 = aTileRect.y + aTileRect.height, - aX1 = aTileRect.x + aTileRect.width; - - // Set up clipping and call Draw(). - aContext.PushState(); - ((nsRenderingContextGTK&)aContext).SetClipRectInPixels( - aTileRect, nsClipCombine_kIntersect); - ((nsRenderingContextGTK&)aContext).UpdateGC(); - - if (mAlphaDepth==8) { - DrawCompositeTile(aContext, aSurface, - aSXOffset, aSYOffset, mWidth, mHeight, - aTileRect.x, aTileRect.y, - aTileRect.width, aTileRect.height); - } else { -#ifdef DEBUG_TILING - printf("Warning: using slow tiling\n"); -#endif - for (PRInt32 y = aY0; y < aY1; y += mHeight + aPadY) - for (PRInt32 x = aX0; x < aX1; x += mWidth + aPadX) - Draw(aContext,aSurface, x,y, - PR_MIN(validWidth, aX1-x), - PR_MIN(validHeight, aY1-y)); - } - - aContext.PopState(); - - return NS_OK; - } - - nsRect clipRect; - PRBool isNonEmpty; - PRBool haveClip = NS_SUCCEEDED(aContext.GetClipRect(clipRect, isNonEmpty)); - if (haveClip && !isNonEmpty) { - return NS_OK; - } - - if (mAlphaDepth == 1) { - if (sNeedSlowTile) { - SlowTile(drawing, aTileRect, aSXOffset, aSYOffset, clipRect, haveClip); - return NS_OK; - } - - GdkGC *tileGC; - GdkGCValues values; - GdkGCValuesMask valuesMask; - - memset(&values, 0, sizeof(GdkGCValues)); - values.fill = GDK_STIPPLED; - values.function = GDK_AND; - values.stipple = mAlphaPixmap; - values.ts_x_origin = aTileRect.x - aSXOffset; - values.ts_y_origin = aTileRect.y - aSYOffset; - valuesMask = GdkGCValuesMask(GDK_GC_FOREGROUND | GDK_GC_FUNCTION | - GDK_GC_FILL | GDK_GC_STIPPLE | - GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN); - tileGC = gdk_gc_new_with_values(drawing->GetDrawable(), &values, valuesMask); - - if (haveClip) { - GdkRectangle gdkrect = {clipRect.x, clipRect.y, - clipRect.width, clipRect.height}; - gdk_gc_set_clip_rectangle(tileGC, &gdkrect); - } - - gdk_draw_rectangle(drawing->GetDrawable(), tileGC, PR_TRUE, - aTileRect.x, aTileRect.y, - aTileRect.width, aTileRect.height); - - gdk_gc_set_fill(tileGC, GDK_TILED); - gdk_gc_set_function(tileGC, GDK_OR); - gdk_gc_set_tile(tileGC, mImagePixmap); - - gdk_draw_rectangle(drawing->GetDrawable(), tileGC, PR_TRUE, - aTileRect.x, aTileRect.y, - aTileRect.width, aTileRect.height); - - gdk_gc_unref(tileGC); - } else { - // In the non-alpha case, gdk can tile for us - TilePixmap(mImagePixmap, drawing->GetDrawable(), aSXOffset, aSYOffset, - aTileRect, clipRect, haveClip); - } - - mFlags = 0; - return NS_OK; -} - - - -//------------------------------------------------------------ - -nsresult nsImageGTK::Optimize(nsIDeviceContext* aContext) -{ - if (!mOptimized) - UpdateCachedImage(); - - if (mAlphaBits && mTrueAlphaBits) { - // 8-bit alpha image turned out to be 1-bit - blacken transparent - // areas so that we can draw it using the fast tile path - for (PRInt32 y = 0; y < mHeight; y++) - for (PRInt32 x = 0; x < mWidth; x++) - if (!mTrueAlphaBits[y * mTrueAlphaRowBytes + x]) { - mImageBits[y * mRowBytes + 3 * x] = 0; - mImageBits[y * mRowBytes + 3 * x + 1] = 0; - mImageBits[y * mRowBytes + 3 * x + 2] = 0; - } - nsRect rect(0, 0, mWidth, mHeight); - ImageUpdated(nsnull, 0, &rect); - UpdateCachedImage(); - } - - if ((gdk_rgb_get_visual()->depth > 8) && (mAlphaDepth != 8)) { - if(nsnull != mImageBits) { - free(mImageBits); - mImageBits = nsnull; - } - - if (nsnull != mAlphaBits) { - free(mAlphaBits); - mAlphaBits = nsnull; - } - } - - if (mTrueAlphaBits) { - free(mTrueAlphaBits); - mTrueAlphaBits = nsnull; - } - - if ((mAlphaDepth==0) && mAlphaPixmap) { - gdk_pixmap_unref(mAlphaPixmap); - mAlphaPixmap = nsnull; - } - - mOptimized = PR_TRUE; - - return NS_OK; -} - -//------------------------------------------------------------ -// lock the image pixels -NS_IMETHODIMP -nsImageGTK::LockImagePixels(PRBool aMaskPixels) -{ - if (!mOptimized) - return NS_OK; - - if (aMaskPixels) { - if (mAlphaDepth != 1 || !mAlphaPixmap) - return NS_OK; - - XImage *xmask = XGetImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap), - GDK_WINDOW_XWINDOW(mAlphaPixmap), - 0, 0, mWidth, mHeight, - AllPlanes, XYPixmap); - - mAlphaBits = (PRUint8*)calloc(mAlphaRowBytes * mHeight, 1); - if (!mAlphaBits) - return NS_ERROR_OUT_OF_MEMORY; - - for (PRInt32 y = 0; y < mHeight; ++y) { - PRUint8 *alphaTarget = mAlphaBits + y*mAlphaRowBytes; - PRUint32 alphaBitPos = 7; - - for (PRInt32 x = 0; x < mWidth; ++x) { - *alphaTarget |= (XGetPixel(xmask, x, y) << alphaBitPos); - if (alphaBitPos-- == 0) { - ++alphaTarget; - alphaBitPos = 7; - } - } - } - - XDestroyImage(xmask); - return NS_OK; - } - - if (!mImagePixmap) - return NS_OK; - - XImage *ximage, *xmask=0; - unsigned pix; - - ximage = XGetImage(GDK_WINDOW_XDISPLAY(mImagePixmap), - GDK_WINDOW_XWINDOW(mImagePixmap), - 0, 0, mWidth, mHeight, - AllPlanes, ZPixmap); - - if ((mAlphaDepth==1) && mAlphaPixmap) - xmask = XGetImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap), - GDK_WINDOW_XWINDOW(mAlphaPixmap), - 0, 0, mWidth, mHeight, - AllPlanes, XYPixmap); - - mImageBits = (PRUint8*)malloc(mSizeImage); - if (!mImageBits) - return NS_ERROR_OUT_OF_MEMORY; - - GdkVisual *visual = gdk_rgb_get_visual(); - GdkColormap *colormap = gdk_rgb_get_cmap(); - - unsigned redScale, greenScale, blueScale, redFill, greenFill, blueFill; - redScale = 8 - visual->red_prec; - greenScale = 8 - visual->green_prec; - blueScale = 8 - visual->blue_prec; - redFill = 0xff >> visual->red_prec; - greenFill = 0xff >> visual->green_prec; - blueFill = 0xff >> visual->blue_prec; - - /* read back the image in the slowest (but simplest) way possible... */ - for (PRInt32 y=0; ytype) { - case GDK_VISUAL_STATIC_GRAY: - case GDK_VISUAL_GRAYSCALE: - case GDK_VISUAL_STATIC_COLOR: - case GDK_VISUAL_PSEUDO_COLOR: - *target++ = colormap->colors[pix].red >>8; - *target++ = colormap->colors[pix].green >>8; - *target++ = colormap->colors[pix].blue >>8; - break; - - case GDK_VISUAL_DIRECT_COLOR: - *target++ = - colormap->colors[(pix&visual->red_mask)>>visual->red_shift].red >> 8; - *target++ = - colormap->colors[(pix&visual->green_mask)>>visual->green_shift].green >> 8; - *target++ = - colormap->colors[(pix&visual->blue_mask)>>visual->blue_shift].blue >> 8; - break; - - case GDK_VISUAL_TRUE_COLOR: - *target++ = - redFill|((pix&visual->red_mask)>>visual->red_shift)<green_mask)>>visual->green_shift)<blue_mask)>>visual->blue_shift)<= dest->mWidth || aDY >= dest->mHeight) - return NS_OK; - - PRUint8 *rgbPtr=0, *alphaPtr=0; - PRUint32 rgbStride, alphaStride; - - rgbPtr = mImageBits; - rgbStride = mRowBytes; - alphaPtr = mAlphaBits; - alphaStride = mAlphaRowBytes; - - PRInt32 y; - PRInt32 ValidWidth = ( aDWidth < ( dest->mWidth - aDX ) ) ? aDWidth : ( dest->mWidth - aDX ); - PRInt32 ValidHeight = ( aDHeight < ( dest->mHeight - aDY ) ) ? aDHeight : ( dest->mHeight - aDY ); - - // now composite the two images together - switch (mAlphaDepth) { - case 1: - { - PRUint8 *dst = dest->mImageBits + aDY*dest->mRowBytes + 3*aDX; - PRUint8 *dstAlpha = dest->mAlphaBits + aDY*dest->mAlphaRowBytes; - PRUint8 *src = rgbPtr; - PRUint8 *alpha = alphaPtr; - PRUint8 offset = aDX & 0x7; // x starts at 0 - int iterations = (ValidWidth+7)/8; // round up - - for (y=0; y= ValidWidth) { - alphaPixels &= 0xff << (8 - (ValidWidth-x)); // no, mask off unused - if (alphaPixels == 0) - continue; // no 1 alpha pixels left - } - if (offset == 0) { - dstAlpha[(aDX+x)>>3] |= alphaPixels; // the cheap aligned case - } - else { - dstAlpha[(aDX+x)>>3] |= alphaPixels >> offset; - // avoid write if no 1's to write - also avoids going past end of array - PRUint8 alphaTemp = alphaPixels << (8U - offset); - if (alphaTemp & 0xff) - dstAlpha[((aDX+x)>>3) + 1] |= alphaTemp; - } - - if (alphaPixels == 0xff) { - // fix - could speed up by gathering a run of 0xff's and doing 1 memcpy - // all 8 pixels set; copy and jump forward - memcpy(dst,src,8*3); - continue; - } - else { - // else mix of 1's and 0's in alphaPixels, do 1 bit at a time - // Don't go past end of line! - PRUint8 *d = dst, *s = src; - for (PRUint8 aMask = 1<<7, j = 0; aMask && j < ValidWidth-x; aMask >>= 1, j++) { - // if this pixel is opaque then copy into the destination image - if (alphaPixels & aMask) { - // might be faster with *d++ = *s++ 3 times? - d[0] = s[0]; - d[1] = s[1]; - d[2] = s[2]; - // dstAlpha bit already set - } - d += 3; - s += 3; - } - } - } - // at end of each line, bump pointers. Use wordy code because of - // bug 127455 to avoid possibility of unsigned underflow - dst = (dst - 3*8*iterations) + dest->mRowBytes; - src = (src - 3*8*iterations) + rgbStride; - alpha = (alpha - iterations) + alphaStride; - dstAlpha += dest->mAlphaRowBytes; - } - } - break; - case 0: - default: - for (y=0; ymImageBits + (y+aDY)*dest->mRowBytes + 3*aDX, - rgbPtr + y*rgbStride, - 3*ValidWidth); - } - - nsRect rect(aDX, aDY, ValidWidth, ValidHeight); - dest->ImageUpdated(nsnull, 0, &rect); - - return NS_OK; -} - -#ifdef MOZ_WIDGET_GTK2 -static void pixbuf_free(guchar* data, gpointer) { - nsMemory::Free(data); -} - -NS_IMETHODIMP_(GdkPixbuf*) -nsImageGTK::GetGdkPixbuf() { - // Init ensures that we only have 24bpp images - NS_ASSERTION(mNumBytesPixel == 3, "Unexpected color depth"); - - nsresult rv = LockImagePixels(PR_FALSE); - NS_ENSURE_SUCCESS(rv, nsnull); - - // Since UnlockImagePixels potentially frees the image data (and since the - // buffer might outlive this object anyway), we have to copy the data. - guchar* pixels = NS_STATIC_CAST(guchar*, - nsMemory::Clone(mImageBits, mRowBytes * mHeight)); - UnlockImagePixels(PR_FALSE); - if (!pixels) - return nsnull; - - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(pixels, - GDK_COLORSPACE_RGB, - PR_FALSE, - 8, - mWidth, - mHeight, - mRowBytes, - pixbuf_free, - nsnull); - if (!pixbuf) - return nsnull; - - if (!GetHasAlphaMask()) { - // No alpha channel -> we are done - return pixbuf; - } - - GdkPixbuf *alphaPixbuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0); - g_object_unref(pixbuf); - if (!alphaPixbuf) - return nsnull; - - LockImagePixels(PR_TRUE); - - PRInt32 alphaBytesPerRow = GetAlphaLineStride(); - PRUint8 *alphaBits = GetAlphaBits(); - - // Run through alphaBits and copy the alpha mask into the pixbuf's - // alpha channel. - PRUint8 *maskRow = alphaBits; - PRUint8 *pixbufRow = gdk_pixbuf_get_pixels(alphaPixbuf); - - gint pixbufRowStride = gdk_pixbuf_get_rowstride(alphaPixbuf); - gint pixbufChannels = gdk_pixbuf_get_n_channels(alphaPixbuf); - - for (PRInt32 y = 0; y < mHeight; ++y) { - PRUint8 *pixbufPixel = pixbufRow; - PRUint8 *maskPixel = maskRow; - - // If using 1-bit alpha, we must expand it to 8-bit - PRUint32 bitPos = 7; - - for (PRInt32 x = 0; x < mWidth; ++x) { - if (mAlphaDepth == 1) { - pixbufPixel[pixbufChannels - 1] = ((*maskPixel >> bitPos) & 1) ? 255 : 0; - if (bitPos-- == 0) { // wrapped around, move forward a byte - ++maskPixel; - bitPos = 7; - } - } else { - pixbufPixel[pixbufChannels - 1] = *maskPixel++; - } - - pixbufPixel += pixbufChannels; - } - - pixbufRow += pixbufRowStride; - maskRow += alphaBytesPerRow; - } - - UnlockImagePixels(PR_TRUE); - return alphaPixbuf; -} - -#endif diff --git a/gfx/src/gtk/nsImageGTK.h b/gfx/src/gtk/nsImageGTK.h deleted file mode 100644 index 1fa94e564874..000000000000 --- a/gfx/src/gtk/nsImageGTK.h +++ /dev/null @@ -1,229 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsImageGTK_h___ -#define nsImageGTK_h___ - -#include "nsIImage.h" - -#include -#include -#include -#include "nsRegion.h" -#ifdef MOZ_WIDGET_GTK2 -#include "nsIGdkPixbufImage.h" -#endif - -class nsDrawingSurfaceGTK; - -class nsImageGTK : -#ifdef MOZ_WIDGET_GTK2 - public nsIGdkPixbufImage -#else - public nsIImage -#endif -{ -public: - nsImageGTK(); - virtual ~nsImageGTK(); - - static void Startup(); - static void Shutdown(); - - NS_DECL_ISUPPORTS - - /** - @see nsIImage.h - */ - virtual PRInt32 GetBytesPix() { return mNumBytesPixel; } - virtual PRInt32 GetHeight(); - virtual PRInt32 GetWidth(); - virtual PRUint8* GetBits(); - virtual void* GetBitInfo(); - virtual PRBool GetIsRowOrderTopToBottom() { return PR_TRUE; } - virtual PRInt32 GetLineStride(); - - virtual nsColorMap* GetColorMap(); - - NS_IMETHOD Draw(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 aX, PRInt32 aY, - PRInt32 aWidth, PRInt32 aHeight); - NS_IMETHOD Draw(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, - PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight); - - NS_IMETHOD DrawToImage(nsIImage* aDstImage, nscoord aDX, nscoord aDY, - nscoord aDWidth, nscoord aDHeight); - - NS_IMETHOD DrawTile(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 aSXOffset, PRInt32 aSYOffset, - PRInt32 aPadX, PRInt32 aPadY, - const nsRect &aTileRect); - - void UpdateCachedImage(); - virtual void ImageUpdated(nsIDeviceContext *aContext, - PRUint8 aFlags, nsRect *aUpdateRect); - virtual PRBool GetIsImageComplete(); - virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, - PRInt32 aDepth, - nsMaskRequirements aMaskRequirements); - - virtual nsresult Optimize(nsIDeviceContext* aContext); - - virtual PRBool GetHasAlphaMask() { return mAlphaBits != nsnull || mAlphaPixmap != nsnull; } - virtual PRUint8* GetAlphaBits(); - virtual PRInt32 GetAlphaLineStride(); - - /** - * Get the alpha depth for the image mask - * @update - lordpixel 2001/05/16 - * @return the alpha mask depth for the image, ie, 0, 1 or 8 - */ - virtual PRInt8 GetAlphaDepth() { - if (mTrueAlphaBits) - return mTrueAlphaDepth; - else - return mAlphaDepth; - } - - NS_IMETHOD LockImagePixels(PRBool aMaskPixels); - NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels); - -#ifdef MOZ_WIDGET_GTK2 - NS_IMETHOD_(GdkPixbuf*) GetGdkPixbuf(); -#endif - -private: - /** - * Calculate the amount of memory needed for the initialization of the image - */ - void ComputeMetrics() { - mRowBytes = (mWidth * mDepth) >> 5; - - if (((PRUint32)mWidth * mDepth) & 0x1F) - mRowBytes++; - mRowBytes <<= 2; - - mSizeImage = mRowBytes * mHeight; - }; - void ComputePaletteSize(PRIntn nBitCount); - -private: - - static unsigned scaled6[1<<6]; - static unsigned scaled5[1<<5]; - - void DrawComposited32(PRBool isLSB, PRBool flipBytes, - PRUint8 *imageOrigin, PRUint32 imageStride, - PRUint8 *alphaOrigin, PRUint32 alphaStride, - unsigned width, unsigned height, - XImage *ximage, unsigned char *readData, unsigned char *srcData); - void DrawComposited24(PRBool isLSB, PRBool flipBytes, - PRUint8 *imageOrigin, PRUint32 imageStride, - PRUint8 *alphaOrigin, PRUint32 alphaStride, - unsigned width, unsigned height, - XImage *ximage, unsigned char *readData, unsigned char *srcData); - void DrawComposited16(PRBool isLSB, PRBool flipBytes, - PRUint8 *imageOrigin, PRUint32 imageStride, - PRUint8 *alphaOrigin, PRUint32 alphaStride, - unsigned width, unsigned height, - XImage *ximage, unsigned char *readData, unsigned char *srcData); - void DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes, - PRUint8 *imageOrigin, PRUint32 imageStride, - PRUint8 *alphaOrigin, PRUint32 alphaStride, - unsigned width, unsigned height, - XImage *ximage, unsigned char *readData, unsigned char *srcData); - inline void DrawComposited(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 srcWidth, PRInt32 srcHeight, - PRInt32 dstWidth, PRInt32 dstHeight, - PRInt32 dstOrigX, PRInt32 dstOrigY, - PRInt32 aDX, PRInt32 aDY, - PRInt32 aDWidth, PRInt32 aDHeight); - inline void DrawCompositeTile(nsIRenderingContext &aContext, - nsIDrawingSurface* aSurface, - PRInt32 aSX, PRInt32 aSY, - PRInt32 aSWidth, PRInt32 aSHeight, - PRInt32 aDX, PRInt32 aDY, - PRInt32 aDWidth, PRInt32 aDHeight); - - inline void TilePixmap(GdkPixmap *src, GdkPixmap *dest, PRInt32 aSXOffset, PRInt32 aSYOffset, - const nsRect &destRect, const nsRect &clipRect, PRBool useClip); - inline void CreateOffscreenPixmap(PRInt32 aWidth, PRInt32 aHeight); - inline void SetupGCForAlpha(GdkGC *aGC, PRInt32 aX, PRInt32 aY); - - void SlowTile(nsDrawingSurfaceGTK *aSurface, const nsRect &aTileRect, - PRInt32 aSXOffset, PRInt32 aSYOffset, const nsRect& aRect, PRBool aIsValid); - - PRUint8 *mImageBits; - GdkPixmap *mImagePixmap; - PRUint8 *mTrueAlphaBits; - PRUint8 *mAlphaBits; - GdkPixmap *mAlphaPixmap; - XImage *mAlphaXImage; - - PRInt32 mWidth; - PRInt32 mHeight; - PRInt32 mRowBytes; - PRInt32 mSizeImage; - - PRInt32 mDecodedX1; // Keeps track of what part of image - PRInt32 mDecodedY1; // has been decoded. - PRInt32 mDecodedX2; - PRInt32 mDecodedY2; - - nsRegion mUpdateRegion; - - // alpha layer members - PRInt32 mAlphaRowBytes; // alpha bytes per row - PRInt32 mTrueAlphaRowBytes; // alpha bytes per row - PRInt8 mAlphaDepth; // alpha layer depth - PRInt8 mTrueAlphaDepth; // alpha layer depth - PRPackedBool mIsSpacer; - PRPackedBool mPendingUpdate; - - PRInt8 mNumBytesPixel; - PRUint8 mFlags; // flags set by ImageUpdated - PRInt8 mDepth; // bits per pixel - - PRPackedBool mOptimized; -}; - -#endif diff --git a/gfx/src/gtk/nsRegionGTK.cpp b/gfx/src/gtk/nsRegionGTK.cpp deleted file mode 100644 index 92d003aa3b96..000000000000 --- a/gfx/src/gtk/nsRegionGTK.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Stuart Parmenter. - * Portions created by the Initial Developer are Copyright (C) 1998-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Stuart Parmenter - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include -#include "nsRegionGTK.h" -#include "xregion.h" -#include "prmem.h" - -#ifdef DEBUG_REGIONS -static int nRegions; -#endif - -GdkRegion *nsRegionGTK::copyRegion = nsnull; - - -nsRegionGTK::nsRegionGTK() -{ -#ifdef DEBUG_REGIONS - ++nRegions; - printf("REGIONS+ = %i\n", nRegions); -#endif - - mRegion = nsnull; -} - -nsRegionGTK::~nsRegionGTK() -{ -#ifdef DEBUG_REGIONS - --nRegions; - printf("REGIONS- = %i\n", nRegions); -#endif - - if (mRegion) - ::gdk_region_destroy(mRegion); - mRegion = nsnull; -} - -NS_IMPL_ISUPPORTS1(nsRegionGTK, nsIRegion) - - -/* static */ void -nsRegionGTK::Shutdown() -{ - if (copyRegion) { - gdk_region_destroy(copyRegion); - copyRegion = nsnull; - } -} - -GdkRegion * -nsRegionGTK::GetCopyRegion() { - if (!copyRegion) copyRegion = gdk_region_new(); - return copyRegion; -} - - - -GdkRegion * -nsRegionGTK::gdk_region_copy(GdkRegion *region) -{ - return gdk_regions_union(region, GetCopyRegion()); -} - -GdkRegion * -nsRegionGTK::gdk_region_from_rect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - GdkRectangle grect; - - grect.x = aX; - grect.y = aY; - grect.width = aWidth; - grect.height = aHeight; - - return ::gdk_region_union_with_rect(GetCopyRegion(), &grect); -} - -nsresult nsRegionGTK::Init(void) -{ - if (mRegion) { - gdk_region_destroy(mRegion); - mRegion = nsnull; - } - - return NS_OK; -} - -void nsRegionGTK::SetTo(const nsIRegion &aRegion) -{ - Init(); - - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - - mRegion = gdk_region_copy(pRegion->mRegion); -} - -void nsRegionGTK::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - Init(); - - mRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight); -} - -void nsRegionGTK::Intersect(const nsIRegion &aRegion) -{ - if(!mRegion) { - NS_WARNING("mRegion is NULL"); - return; - } - - nsRegionGTK * pRegion = (nsRegionGTK *)&aRegion; - - GdkRegion *nRegion = ::gdk_regions_intersect(mRegion, pRegion->mRegion); - ::gdk_region_destroy(mRegion); - mRegion = nRegion; -} - -void nsRegionGTK::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - if(!mRegion) { - NS_WARNING("mRegion is NULL"); - return; - } - - GdkRegion *tRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight); - - GdkRegion *nRegion = ::gdk_regions_intersect(mRegion, tRegion); - ::gdk_region_destroy(tRegion); - ::gdk_region_destroy(mRegion); - mRegion = nRegion; -} - -void nsRegionGTK::Union(const nsIRegion &aRegion) -{ - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - - if (pRegion->mRegion && !::gdk_region_empty(pRegion->mRegion)) { - if (mRegion) { - if (::gdk_region_empty(mRegion)) { - ::gdk_region_destroy(mRegion); - mRegion = gdk_region_copy(pRegion->mRegion); - } else { - GdkRegion *nRegion = ::gdk_regions_union(mRegion, pRegion->mRegion); - ::gdk_region_destroy(mRegion); - mRegion = nRegion; - } - } else - mRegion = gdk_region_copy(pRegion->mRegion); - } -} - -void nsRegionGTK::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - if (mRegion) { - GdkRectangle grect; - - grect.x = aX; - grect.y = aY; - grect.width = aWidth; - grect.height = aHeight; - - if (grect.width > 0 && grect.height > 0) { - if (::gdk_region_empty(mRegion)) { - ::gdk_region_destroy(mRegion); - mRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight); - } else { - GdkRegion *nRegion = ::gdk_region_union_with_rect(mRegion, &grect); - ::gdk_region_destroy(mRegion); - mRegion = nRegion; - } - } - } else { - mRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight); - } -} - -void nsRegionGTK::Subtract(const nsIRegion &aRegion) -{ - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - if (pRegion->mRegion) { - if (mRegion) { - GdkRegion *nRegion = ::gdk_regions_subtract(mRegion, pRegion->mRegion); - ::gdk_region_destroy(mRegion); - mRegion = nRegion; - } else { - mRegion = ::gdk_regions_subtract(GetCopyRegion(), pRegion->mRegion); - } - } -} - -void nsRegionGTK::Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - if (mRegion) { - GdkRegion *tRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight); - - GdkRegion *nRegion = ::gdk_regions_subtract(mRegion, tRegion); - ::gdk_region_destroy(mRegion); - ::gdk_region_destroy(tRegion); - mRegion = nRegion; - } else { - GdkRegion *tRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight); - mRegion = ::gdk_regions_subtract(GetCopyRegion(), tRegion); - ::gdk_region_destroy(tRegion); - } -} - -PRBool nsRegionGTK::IsEmpty(void) -{ - if (!mRegion) - return PR_TRUE; - return (::gdk_region_empty(mRegion)); -} - -PRBool nsRegionGTK::IsEqual(const nsIRegion &aRegion) -{ - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - - if (mRegion && pRegion->mRegion) { - return(::gdk_region_equal(mRegion, pRegion->mRegion)); - } else if (!mRegion && !pRegion->mRegion) { - return PR_TRUE; - } else if ((mRegion && !pRegion->mRegion) || (!mRegion && pRegion->mRegion)) { - return PR_FALSE; - } - - return PR_FALSE; -} - -void nsRegionGTK::GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight) -{ - if (mRegion) { - GdkRectangle rect; - - ::gdk_region_get_clipbox(mRegion, &rect); - - *aX = rect.x; - *aY = rect.y; - *aWidth = rect.width; - *aHeight = rect.height; - } else { - *aX = 0; - *aY = 0; - *aWidth = 0; - *aHeight = 0; - } -} - -void nsRegionGTK::Offset(PRInt32 aXOffset, PRInt32 aYOffset) -{ - if (mRegion) { - ::gdk_region_offset(mRegion, aXOffset, aYOffset); - } -} - -PRBool nsRegionGTK::ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - if (mRegion) { - GdkOverlapType containment; - GdkRectangle rect; - - rect.x = aX; - rect.y = aY; - rect.width = aWidth; - rect.height = aHeight; - - containment = ::gdk_region_rect_in(mRegion, &rect); - - if (containment != GDK_OVERLAP_RECTANGLE_OUT) - return PR_TRUE; - } - return PR_FALSE; -} - -NS_IMETHODIMP nsRegionGTK::GetRects(nsRegionRectSet **aRects) -{ - - *aRects = nsnull; - - if (!mRegion) - return NS_OK; - - nsRegionRectSet *rects = nsnull; - GdkRegionPrivate *priv = nsnull; - Region pRegion; - int nbox = 0; - BOX *pbox = nsnull; - nsRegionRect *rect = nsnull; - - priv = (GdkRegionPrivate *)mRegion; - pRegion = priv->xregion; - pbox = pRegion->rects; - nbox = pRegion->numRects; - - NS_ASSERTION(!(nsnull == aRects), "bad ptr"); - - //code lifted from old xfe. MMP - - rects = *aRects; - - if ((nsnull == rects) || (rects->mRectsLen < (PRUint32)nbox)) - { - void *buf = PR_Realloc(rects, sizeof(nsRegionRectSet) + (sizeof(nsRegionRect) * (nbox - 1))); - - if (nsnull == buf) - { - if (nsnull != rects) - rects->mNumRects = 0; - - return NS_OK; - } - - rects = (nsRegionRectSet *)buf; - rects->mRectsLen = nbox; - } - - rects->mNumRects = nbox; - rects->mArea = 0; - rect = &rects->mRects[0]; - - while (nbox--) - { - rect->x = pbox->x1; - rect->width = (pbox->x2 - pbox->x1); - rect->y = pbox->y1; - rect->height = (pbox->y2 - pbox->y1); - - rects->mArea += rect->width * rect->height; - - pbox++; - rect++; - } - - *aRects = rects; - - return NS_OK; -} - -NS_IMETHODIMP nsRegionGTK::FreeRects(nsRegionRectSet *aRects) -{ - if (nsnull != aRects) - PR_Free((void *)aRects); - - return NS_OK; -} - -NS_IMETHODIMP nsRegionGTK::GetNativeRegion(void *&aRegion) const -{ - aRegion = (void *)mRegion; - return NS_OK; -} - -NS_IMETHODIMP nsRegionGTK::GetRegionComplexity(nsRegionComplexity &aComplexity) const -{ - // cast to avoid const-ness problems on some compilers - if (((nsRegionGTK*)this)->IsEmpty()) - aComplexity = eRegionComplexity_empty; - else - aComplexity = eRegionComplexity_complex; - - return NS_OK; -} - -void nsRegionGTK::SetRegionEmpty() -{ - if (!IsEmpty()) { - ::gdk_region_destroy(mRegion); - } -} - -NS_IMETHODIMP nsRegionGTK::GetNumRects(PRUint32 *aRects) const -{ - if (!mRegion) - *aRects = 0; - - GdkRegionPrivate *priv = (GdkRegionPrivate *)mRegion; - Region pRegion = priv->xregion; - - *aRects = pRegion->numRects; - - return NS_OK; -} diff --git a/gfx/src/gtk/nsRegionGTK.h b/gfx/src/gtk/nsRegionGTK.h deleted file mode 100644 index e28559dfe888..000000000000 --- a/gfx/src/gtk/nsRegionGTK.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Stuart Parmenter. - * Portions created by the Initial Developer are Copyright (C) 1998-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Stuart Parmenter - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsRegionGTK_h___ -#define nsRegionGTK_h___ - -#include "nsIRegion.h" - -#include - -class nsRegionGTK : public nsIRegion -{ -public: - nsRegionGTK(); - virtual ~nsRegionGTK(); - - NS_DECL_ISUPPORTS - - virtual nsresult Init(); - - virtual void SetTo(const nsIRegion &aRegion); - virtual void SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); - virtual void Intersect(const nsIRegion &aRegion); - virtual void Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); - virtual void Union(const nsIRegion &aRegion); - virtual void Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); - virtual void Subtract(const nsIRegion &aRegion); - virtual void Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); - virtual PRBool IsEmpty(void); - virtual PRBool IsEqual(const nsIRegion &aRegion); - virtual void GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight); - virtual void Offset(PRInt32 aXOffset, PRInt32 aYOffset); - virtual PRBool ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); - NS_IMETHOD GetRects(nsRegionRectSet **aRects); - NS_IMETHOD FreeRects(nsRegionRectSet *aRects); - NS_IMETHOD GetNativeRegion(void *&aRegion) const; - NS_IMETHOD GetRegionComplexity(nsRegionComplexity &aComplexity) const; - NS_IMETHOD GetNumRects(PRUint32 *aRects) const; - -private: - - GdkRegion *mRegion; -}; - -#endif // nsRegionGTK_h___ diff --git a/gfx/src/gtk/nsRegionGTK2.cpp b/gfx/src/gtk/nsRegionGTK2.cpp deleted file mode 100644 index 527125be440c..000000000000 --- a/gfx/src/gtk/nsRegionGTK2.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Stuart Parmenter. - * Portions created by the Initial Developer are Copyright (C) 1998-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Stuart Parmenter - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include "nsRegionGTK.h" -#include "nsMemory.h" - -#ifdef DEBUG_REGIONS -static int nRegions; -#endif - -nsRegionGTK::nsRegionGTK() -{ -#ifdef DEBUG_REGIONS - ++nRegions; - printf("REGIONS+ = %i\n", nRegions); -#endif - - mRegion = nsnull; -} - -nsRegionGTK::~nsRegionGTK() -{ -#ifdef DEBUG_REGIONS - --nRegions; - printf("REGIONS- = %i\n", nRegions); -#endif - - if (mRegion) - gdk_region_destroy(mRegion); - mRegion = nsnull; -} - -NS_IMPL_ISUPPORTS1(nsRegionGTK, nsIRegion) - -nsresult nsRegionGTK::Init(void) -{ - if (mRegion) { - gdk_region_destroy(mRegion); - mRegion = nsnull; - } - - return NS_OK; -} - -void nsRegionGTK::SetTo(const nsIRegion &aRegion) -{ - Init(); - - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - - mRegion = gdk_region_copy(pRegion->mRegion); -} - -void nsRegionGTK::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - Init(); - - GdkRectangle rect; - rect.x = aX; - rect.y = aY; - rect.width = aWidth; - rect.height = aHeight; - - mRegion = gdk_region_rectangle(&rect); -} - -void nsRegionGTK::Intersect(const nsIRegion &aRegion) -{ - if(!mRegion) { - NS_WARNING("mRegion is NULL"); - return; - } - - nsRegionGTK * pRegion = (nsRegionGTK *)&aRegion; - - gdk_region_intersect(mRegion, pRegion->mRegion); -} - -void nsRegionGTK::Intersect(PRInt32 aX, PRInt32 aY, - PRInt32 aWidth, PRInt32 aHeight) -{ - if(!mRegion) { - NS_WARNING("mRegion is NULL"); - return; - } - - GdkRectangle rect; - rect.x = aX; - rect.y = aY; - rect.width = aWidth; - rect.height = aHeight; - - GdkRegion *tRegion = gdk_region_rectangle(&rect); - - gdk_region_intersect(mRegion, tRegion); - gdk_region_destroy(tRegion); -} - -void nsRegionGTK::Union(const nsIRegion &aRegion) -{ - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - - if (pRegion->mRegion && !gdk_region_empty(pRegion->mRegion)) { - if (mRegion) { - if (gdk_region_empty(mRegion)) { - gdk_region_destroy(mRegion); - mRegion = gdk_region_copy(pRegion->mRegion); - } else { - gdk_region_union(mRegion, pRegion->mRegion); - } - } else - mRegion = gdk_region_copy(pRegion->mRegion); - } -} - -void nsRegionGTK::Union(PRInt32 aX, PRInt32 aY, - PRInt32 aWidth, PRInt32 aHeight) -{ - GdkRectangle grect; - - grect.x = aX; - grect.y = aY; - grect.width = aWidth; - grect.height = aHeight; - - if (mRegion) { - if (grect.width > 0 && grect.height > 0) { - if (gdk_region_empty(mRegion)) { - gdk_region_destroy(mRegion); - mRegion = gdk_region_rectangle(&grect); - } else { - gdk_region_union_with_rect(mRegion, &grect); - } - } - } else { - mRegion = gdk_region_rectangle(&grect); - } -} - -void nsRegionGTK::Subtract(const nsIRegion &aRegion) -{ - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - if (pRegion->mRegion) { - if (mRegion) { - gdk_region_subtract(mRegion, pRegion->mRegion); - } else { - mRegion = gdk_region_new(); - gdk_region_subtract(mRegion, pRegion->mRegion); - } - } -} - -void nsRegionGTK::Subtract(PRInt32 aX, PRInt32 aY, - PRInt32 aWidth, PRInt32 aHeight) -{ - GdkRectangle rect; - rect.x = aX; - rect.y = aY; - rect.width = aWidth; - rect.height = aHeight; - GdkRegion *tRegion = gdk_region_rectangle(&rect); - - if (mRegion) { - gdk_region_subtract(mRegion, tRegion); - } else { - NS_WARNING("subtracting from a non-region?"); - mRegion = gdk_region_new(); - gdk_region_subtract(mRegion, tRegion); - } - - gdk_region_destroy(tRegion); -} - -PRBool nsRegionGTK::IsEmpty(void) -{ - if (!mRegion) - return PR_TRUE; - return (gdk_region_empty(mRegion)); -} - -PRBool nsRegionGTK::IsEqual(const nsIRegion &aRegion) -{ - nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion; - - if (mRegion && pRegion->mRegion) { - return(gdk_region_equal(mRegion, pRegion->mRegion)); - } else if (!mRegion && !pRegion->mRegion) { - return PR_TRUE; - } else if ((mRegion && !pRegion->mRegion) || (!mRegion && pRegion->mRegion)) { - return PR_FALSE; - } - - return PR_FALSE; -} - -void nsRegionGTK::GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight) -{ - if (mRegion) { - GdkRectangle rect; - - gdk_region_get_clipbox(mRegion, &rect); - - *aX = rect.x; - *aY = rect.y; - *aWidth = rect.width; - *aHeight = rect.height; - } else { - *aX = 0; - *aY = 0; - *aWidth = 0; - *aHeight = 0; - } -} - -void nsRegionGTK::Offset(PRInt32 aXOffset, PRInt32 aYOffset) -{ - if (mRegion) { - gdk_region_offset(mRegion, aXOffset, aYOffset); - } -} - -PRBool nsRegionGTK::ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) -{ - if (mRegion) { - GdkOverlapType containment; - GdkRectangle rect; - - rect.x = aX; - rect.y = aY; - rect.width = aWidth; - rect.height = aHeight; - - containment = gdk_region_rect_in(mRegion, &rect); - - if (containment != GDK_OVERLAP_RECTANGLE_OUT) - return PR_TRUE; - } - return PR_FALSE; -} - -NS_IMETHODIMP nsRegionGTK::GetRects(nsRegionRectSet **aRects) -{ - nsRegionRectSet *retval; - nsRegionRect *regionrect; - - *aRects = nsnull; - - if (!mRegion) - return NS_OK; - - GdkRectangle *rects = nsnull; - gint nrects = 0; - - gdk_region_get_rectangles(mRegion, &rects, &nrects); - - // There are no rectangles in this region but we still need to - // return an empty structure. - if (!nrects) { - retval = (nsRegionRectSet *)nsMemory::Alloc(sizeof(nsRegionRectSet)); - if (!retval) - return NS_ERROR_OUT_OF_MEMORY; - - retval->mNumRects = 0; - retval->mRectsLen = 0; - retval->mArea = 0; - - *aRects = retval; - - return NS_OK; - } - - // allocate space for our return values - retval = (nsRegionRectSet *) - nsMemory::Alloc(sizeof(nsRegionRectSet) + - (sizeof(nsRegionRect) * (nrects - 1))); - if (!retval) - return NS_ERROR_OUT_OF_MEMORY; - - regionrect = &retval->mRects[0]; - retval->mNumRects = nrects; - retval->mRectsLen = nrects; - - int currect = 0; - while (currect < nrects) { - regionrect->x = rects[currect].x; - regionrect->y = rects[currect].y; - regionrect->width = rects[currect].width; - regionrect->height = rects[currect].height; - - retval->mArea += rects[currect].width * rects[currect].height; - - currect++; - regionrect++; - } - - // they are allocated as one lump - g_free(rects); - - *aRects = retval; - return NS_OK; -} - -NS_IMETHODIMP nsRegionGTK::FreeRects(nsRegionRectSet *aRects) -{ - if (nsnull != aRects) - nsMemory::Free(aRects); - - return NS_OK; -} - -NS_IMETHODIMP nsRegionGTK::GetNativeRegion(void *&aRegion) const -{ - aRegion = (void *)mRegion; - return NS_OK; -} - -NS_IMETHODIMP nsRegionGTK::GetRegionComplexity(nsRegionComplexity &aComplexity) const -{ - // cast to avoid const-ness problems on some compilers - if (((nsRegionGTK*)this)->IsEmpty()) - aComplexity = eRegionComplexity_empty; - else - aComplexity = eRegionComplexity_complex; - - return NS_OK; -} - -NS_IMETHODIMP nsRegionGTK::GetNumRects(PRUint32 *aRects) const -{ - if (!mRegion) - *aRects = 0; - - GdkRectangle *rects = nsnull; - gint nrects = 0; - - gdk_region_get_rectangles(mRegion, &rects, &nrects); - - // freed as one lump - g_free(rects); - - *aRects = nrects; - - return NS_OK; -} diff --git a/gfx/src/gtk/nsRenderingContextGTK.cpp b/gfx/src/gtk/nsRenderingContextGTK.cpp deleted file mode 100644 index 054c90990d6e..000000000000 --- a/gfx/src/gtk/nsRenderingContextGTK.cpp +++ /dev/null @@ -1,1473 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Tomi Leppikangas - * Roland Mainz - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsFixedSizeAllocator.h" -#include "nsRenderingContextGTK.h" -#include "nsRegionGTK.h" -#include "nsImageGTK.h" -#include "nsGraphicsStateGTK.h" -#include "nsCompressedCharMap.h" -#include -#include "nsGCCache.h" -#include -#include -#include "prmem.h" -#include "prenv.h" - -#include "nsIFontMetricsGTK.h" -#include "nsDeviceContextGTK.h" -#include "nsFontMetricsUtils.h" - -#ifdef MOZ_WIDGET_GTK2 -#include -#endif - -NS_IMPL_ISUPPORTS1(nsRenderingContextGTK, nsIRenderingContext) - -#define NSRECT_TO_GDKRECT(ns,gdk) \ - PR_BEGIN_MACRO \ - gdk.x = ns.x; \ - gdk.y = ns.y; \ - gdk.width = ns.width; \ - gdk.height = ns.height; \ - PR_END_MACRO - -static nsGCCache *gcCache = nsnull; -static nsFixedSizeAllocator *gStatePool = nsnull; - -nsRenderingContextGTK::nsRenderingContextGTK() -{ - mFontMetrics = nsnull; - mContext = nsnull; - mSurface = nsnull; - mOffscreenSurface = nsnull; - mCurrentColor = NS_RGB(255, 255, 255); // set it to white - mCurrentLineStyle = nsLineStyle_kSolid; - mTranMatrix = nsnull; - mP2T = 1.0f; - mClipRegion = nsnull; - mDrawStringBuf = nsnull; - mGC = nsnull; - - mFunction = GDK_COPY; - - PushState(); -} - -nsRenderingContextGTK::~nsRenderingContextGTK() -{ - // Destroy the State Machine - PRInt32 cnt = mStateCache.Count(); - - while (--cnt >= 0) - PopState(); - - if (mTranMatrix) { - if (gStatePool) { - mTranMatrix->~nsTransform2D(); - gStatePool->Free(mTranMatrix, sizeof(nsTransform2D)); - } else { - delete mTranMatrix; - } - } - NS_IF_RELEASE(mOffscreenSurface); - NS_IF_RELEASE(mFontMetrics); - NS_IF_RELEASE(mContext); - - if (nsnull != mDrawStringBuf) { - delete [] mDrawStringBuf; - } - - if (nsnull != mGC) { - gdk_gc_unref(mGC); - } -} - -/*static*/ nsresult -nsRenderingContextGTK::Shutdown() -{ - delete gcCache; - delete gStatePool; - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::Init(nsIDeviceContext* aContext, - nsIWidget *aWindow) -{ - mContext = aContext; - NS_IF_ADDREF(mContext); - -// ::gdk_rgb_init(); - - mSurface = new nsDrawingSurfaceGTK(); - - if (mSurface) - { - if (!aWindow) return NS_ERROR_NULL_POINTER; - - // we want to ref the window here so that we can unref in the drawing surface. - // otherwise, we can not unref and that causes windows that are created in the - // drawing surface not to be freed. - GdkDrawable *win = (GdkDrawable*)aWindow->GetNativeData(NS_NATIVE_WINDOW); - if (win) - gdk_window_ref((GdkWindow*)win); - else - { - GtkWidget *w = (GtkWidget *) aWindow->GetNativeData(NS_NATIVE_WIDGET); - - if (!w) - { - delete mSurface; - mSurface = nsnull; - return NS_ERROR_NULL_POINTER; - } - - win = gdk_pixmap_new(nsnull, - w->allocation.width, - w->allocation.height, - gdk_rgb_get_visual()->depth); -#ifdef MOZ_WIDGET_GTK2 - gdk_drawable_set_colormap(win, gdk_rgb_get_colormap()); -#endif - } - - GdkGC *gc = (GdkGC *)aWindow->GetNativeData(NS_NATIVE_GRAPHIC); - mSurface->Init(win,gc); - - mOffscreenSurface = mSurface; - - NS_ADDREF(mSurface); - - // aWindow->GetNativeData() ref'd the gc. - // only Win32 has a FreeNativeData() method. - // so do this manually here. - gdk_gc_unref(gc); - } - return (CommonInit()); -} - -NS_IMETHODIMP nsRenderingContextGTK::Init(nsIDeviceContext* aContext, - nsIDrawingSurface* aSurface) -{ - mContext = aContext; - NS_IF_ADDREF(mContext); - - mSurface = (nsDrawingSurfaceGTK *) aSurface; - NS_ADDREF(mSurface); - mOffscreenSurface = mSurface; - - return (CommonInit()); -} - -NS_IMETHODIMP nsRenderingContextGTK::CommonInit() -{ - mP2T = mContext->DevUnitsToAppUnits(); - float app2dev; - app2dev = mContext->AppUnitsToDevUnits(); - mTranMatrix->AddScale(app2dev, app2dev); - - return NS_OK; -} - -void* -nsRenderingContextGTK::GetNativeGraphicData(GraphicDataType aType) -{ - if (aType == NATIVE_GDK_DRAWABLE) - return mSurface->GetDrawable(); - return nsnull; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetHints(PRUint32& aResult) -{ - PRUint32 result = 0; - - // Most X servers implement 8 bit text rendering a lot faster than - // XChar2b rendering. In addition, we can avoid the PRUnichar to - // XChar2b conversion. So we set this bit... - result |= NS_RENDERING_HINT_FAST_8BIT_TEXT; - - // XXX see if we are rendering to the local display or to a remote - // dispaly and set the NS_RENDERING_HINT_REMOTE_RENDERING accordingly - - // see if the font metrics has anything more to offer - result |= NS_FontMetricsGetHints(); - - aResult = result; - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::LockDrawingSurface(PRInt32 aX, PRInt32 aY, - PRUint32 aWidth, PRUint32 aHeight, - void **aBits, PRInt32 *aStride, - PRInt32 *aWidthBytes, PRUint32 aFlags) -{ - PushState(); - - return mSurface->Lock(aX, aY, aWidth, aHeight, - aBits, aStride, aWidthBytes, aFlags); -} - -NS_IMETHODIMP nsRenderingContextGTK::UnlockDrawingSurface(void) -{ - PopState(); - - mSurface->Unlock(); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::SelectOffScreenDrawingSurface(nsIDrawingSurface* aSurface) -{ - if (nsnull == aSurface) - mSurface = mOffscreenSurface; - else - mSurface = (nsDrawingSurfaceGTK *)aSurface; - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetDrawingSurface(nsIDrawingSurface* *aSurface) -{ - *aSurface = mSurface; - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::Reset() -{ -#ifdef DEBUG - g_print("nsRenderingContextGTK::Reset() called\n"); -#endif - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetDeviceContext(nsIDeviceContext *&aContext) -{ - NS_IF_ADDREF(mContext); - aContext = mContext; - return NS_OK; -} -#if 0 -NS_IMETHODIMP nsRenderingContextGTK::PushState(PRInt32 aFlags) -{ - // Get a new GS -#ifdef USE_GS_POOL - nsGraphicsState *state = nsGraphicsStatePool::GetNewGS(); -#else - nsGraphicsState *state = new nsGraphicsState; -#endif - // Push into this state object, add to vector - if (!state) - return NS_ERROR_FAILURE; - - if (aFlags & NS_STATE_COLOR) { - state->mColor = mCurrentColor; - } - - if (aFlags & NS_STATE_TRANSFORM) { - state->mMatrix = mTranMatrix; - if (nsnull == mTranMatrix) { - mTranMatrix = new nsTransform2D(); - } else { - mTranMatrix = new nsTransform2D(mTranMatrix); - } - } - - if (aFlags & NS_STATE_FONT) { - NS_IF_ADDREF(mFontMetrics); - state->mFontMetrics = mFontMetrics; - } - - if (aFlags & NS_STATE_CLIP) { - state->mClipRegion = mClipRegion; - } - - if (aFlags & NS_STATE_LINESTYLE) { - state->mLineStyle = mCurrentLineStyle; - } - - mStateCache.AppendElement(state); - - return NS_OK; -} -#endif - -NS_IMETHODIMP nsRenderingContextGTK::PushState(void) -{ - // Get a new GS - if (!gStatePool) { - gStatePool = new nsFixedSizeAllocator(); - size_t sizes[] = {sizeof(nsGraphicsState), sizeof(nsTransform2D)}; - if (gStatePool) - gStatePool->Init("GTKStatePool", sizes, sizeof(sizes)/sizeof(size_t), - sizeof(nsGraphicsState)*64); - } - - nsGraphicsState *state = nsnull; - if (gStatePool) { - void *space = gStatePool->Alloc(sizeof(nsGraphicsState)); - if (space) - state = ::new(space) nsGraphicsState; - } else { - state = new nsGraphicsState; - } - - // Push into this state object, add to vector - if (!state) - return NS_ERROR_FAILURE; - - state->mMatrix = mTranMatrix; - - if (gStatePool) { - void *space = gStatePool->Alloc(sizeof(nsTransform2D)); - if (mTranMatrix) - mTranMatrix = ::new(space) nsTransform2D(mTranMatrix); - else - mTranMatrix = ::new(space) nsTransform2D(); - } else { - if (mTranMatrix) - mTranMatrix = ::new nsTransform2D(mTranMatrix); - else - mTranMatrix = ::new nsTransform2D(); - } - - // set state to mClipRegion.. SetClip{Rect,Region}() will do copy-on-write stuff - state->mClipRegion = mClipRegion; - - NS_IF_ADDREF(mFontMetrics); - state->mFontMetrics = mFontMetrics; - - state->mColor = mCurrentColor; - state->mLineStyle = mCurrentLineStyle; - - mStateCache.AppendElement(state); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::PopState(void) -{ - PRUint32 cnt = mStateCache.Count(); - nsGraphicsState * state; - - if (cnt > 0) { - state = (nsGraphicsState *)mStateCache.ElementAt(cnt - 1); - mStateCache.RemoveElementAt(cnt - 1); - - // Assign all local attributes from the state object just popped - if (state->mMatrix) { - if (mTranMatrix) { - if (gStatePool) { - mTranMatrix->~nsTransform2D(); - gStatePool->Free(mTranMatrix, sizeof(nsTransform2D)); - } else { - delete mTranMatrix; - } - } - mTranMatrix = state->mMatrix; - } - - mClipRegion.swap(state->mClipRegion); - - if (state->mFontMetrics && (mFontMetrics != state->mFontMetrics)) - SetFont(state->mFontMetrics); - - if (state->mColor != mCurrentColor) - SetColor(state->mColor); - - if (state->mLineStyle != mCurrentLineStyle) - SetLineStyle(state->mLineStyle); - - // Delete this graphics state object - if (gStatePool) { - state->~nsGraphicsState(); - gStatePool->Free(state, sizeof(nsGraphicsState)); - } else { - delete state; - } - } - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::IsVisibleRect(const nsRect& aRect, - PRBool &aVisible) -{ - aVisible = PR_TRUE; - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetClipRect(nsRect &aRect, PRBool &aClipValid) -{ - PRInt32 x, y, w, h; - - if (!mClipRegion) - return NS_ERROR_FAILURE; - - if (!mClipRegion->IsEmpty()) { - mClipRegion->GetBoundingBox(&x,&y,&w,&h); - aRect.SetRect(x,y,w,h); - aClipValid = PR_TRUE; - } else { - aRect.SetRect(0,0,0,0); - aClipValid = PR_FALSE; - } - - return NS_OK; -} - -#ifdef DEBUG -// #define TRACE_SET_CLIP -#endif - -#ifdef TRACE_SET_CLIP -static char * -nsClipCombine_to_string(nsClipCombine aCombine) -{ - switch(aCombine) - { - case nsClipCombine_kIntersect: - return "nsClipCombine_kIntersect"; - break; - - case nsClipCombine_kUnion: - return "nsClipCombine_kUnion"; - break; - - case nsClipCombine_kSubtract: - return "nsClipCombine_kSubtract"; - break; - - case nsClipCombine_kReplace: - return "nsClipCombine_kReplace"; - break; - } - - return "something got screwed"; -} -#endif // TRACE_SET_CLIP - -void -nsRenderingContextGTK::CreateClipRegion() -{ - // We have 3 cases to deal with: - // 1 - There is no mClipRegion -> Create one - // 2 - There is an mClipRegion shared w/ stack -> Duplicate and unshare - // 3 - There is an mClipRegion and its not shared -> return - - if (mClipRegion) { - PRUint32 cnt = mStateCache.Count(); - - if (cnt > 0) { - nsGraphicsState *state; - state = (nsGraphicsState *)mStateCache.ElementAt(cnt - 1); - - if (state->mClipRegion == mClipRegion) { - mClipRegion = new nsRegionGTK; - if (mClipRegion) { - mClipRegion->SetTo(*state->mClipRegion); - } - } - } - } else { - - PRUint32 w, h; - mSurface->GetSize(&w, &h); - - mClipRegion = new nsRegionGTK; - if (mClipRegion) { - mClipRegion->Init(); - mClipRegion->SetTo(0, 0, w, h); - } - } -} - -NS_IMETHODIMP nsRenderingContextGTK::SetClipRect(const nsRect& aRect, - nsClipCombine aCombine) -{ - nsRect trect = aRect; - mTranMatrix->TransformCoord(&trect.x, &trect.y, - &trect.width, &trect.height); - SetClipRectInPixels(trect, aCombine); - return NS_OK; -} - -void nsRenderingContextGTK::SetClipRectInPixels(const nsRect& aRect, - nsClipCombine aCombine) -{ - CreateClipRegion(); - -#ifdef TRACE_SET_CLIP - printf("nsRenderingContextGTK::SetClipRect(%s)\n", - nsClipCombine_to_string(aCombine)); -#endif // TRACE_SET_CLIP - - switch(aCombine) - { - case nsClipCombine_kIntersect: - mClipRegion->Intersect(aRect.x,aRect.y,aRect.width,aRect.height); - break; - case nsClipCombine_kUnion: - mClipRegion->Union(aRect.x,aRect.y,aRect.width,aRect.height); - break; - case nsClipCombine_kSubtract: - mClipRegion->Subtract(aRect.x,aRect.y,aRect.width,aRect.height); - break; - case nsClipCombine_kReplace: - mClipRegion->SetTo(aRect.x,aRect.y,aRect.width,aRect.height); - break; - } -#if 0 - nscolor color = mCurrentColor; - SetColor(NS_RGB(255, 0, 0)); - FillRect(aRect); - SetColor(color); -#endif -} - -void nsRenderingContextGTK::UpdateGC() -{ - GdkGCValues values; - GdkGCValuesMask valuesMask; - - if (mGC) - gdk_gc_unref(mGC); - - memset(&values, 0, sizeof(GdkGCValues)); - - values.foreground.pixel = - gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(mCurrentColor)); - values.foreground.red = (NS_GET_R(mCurrentColor) << 8) | NS_GET_R(mCurrentColor); - values.foreground.green = (NS_GET_G(mCurrentColor) << 8) | NS_GET_G(mCurrentColor); - values.foreground.blue = (NS_GET_B(mCurrentColor) << 8) | NS_GET_B(mCurrentColor); - valuesMask = GDK_GC_FOREGROUND; - -#ifdef MOZ_ENABLE_COREXFONTS - if (mFontMetrics) { - GdkFont *font = mFontMetrics->GetCurrentGDKFont(); - if (font) { - valuesMask = GdkGCValuesMask(valuesMask | GDK_GC_FONT); - values.font = font; - } - } -#endif - - valuesMask = GdkGCValuesMask(valuesMask | GDK_GC_LINE_STYLE); - values.line_style = mLineStyle; - - valuesMask = GdkGCValuesMask(valuesMask | GDK_GC_FUNCTION); - values.function = mFunction; - - GdkRegion *rgn = nsnull; - if (mClipRegion) { - mClipRegion->GetNativeRegion((void*&)rgn); - } - - if (!gcCache) { - gcCache = new nsGCCache(); - if (!gcCache) return; - } - - mGC = gcCache->GetGC(mOffscreenSurface->GetDrawable(), - &values, - valuesMask, - rgn); - - if (mDashes) - ::XSetDashes(GDK_DISPLAY(), GDK_GC_XGC(mGC), - 0, mDashList, mDashes); -} - -NS_IMETHODIMP nsRenderingContextGTK::SetClipRegion(const nsIRegion& aRegion, - nsClipCombine aCombine) -{ - CreateClipRegion(); - - switch(aCombine) - { - case nsClipCombine_kIntersect: - mClipRegion->Intersect(aRegion); - break; - case nsClipCombine_kUnion: - mClipRegion->Union(aRegion); - break; - case nsClipCombine_kSubtract: - mClipRegion->Subtract(aRegion); - break; - case nsClipCombine_kReplace: - mClipRegion->SetTo(aRegion); - break; - } - - return NS_OK; -} - -/** - * Fills in |aRegion| with a copy of the current clip region. - */ -NS_IMETHODIMP nsRenderingContextGTK::CopyClipRegion(nsIRegion &aRegion) -{ - if (!mClipRegion) - return NS_ERROR_FAILURE; - - aRegion.SetTo(*mClipRegion); - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetClipRegion(nsIRegion **aRegion) -{ - nsresult rv = NS_ERROR_FAILURE; - - if (!aRegion || !mClipRegion) - return NS_ERROR_NULL_POINTER; - - if (mClipRegion) { - if (*aRegion) { // copy it, they should be using CopyClipRegion - (*aRegion)->SetTo(*mClipRegion); - rv = NS_OK; - } else { - nsCOMPtr newRegion = new nsRegionGTK; - if (newRegion) { - newRegion->Init(); - newRegion->SetTo(*mClipRegion); - NS_ADDREF(*aRegion = newRegion); - } - } - } else { -#ifdef DEBUG - printf("null clip region, can't make a valid copy\n"); -#endif - rv = NS_ERROR_FAILURE; - } - - return rv; -} - -NS_IMETHODIMP nsRenderingContextGTK::SetColor(nscolor aColor) -{ - if (nsnull == mContext) - return NS_ERROR_FAILURE; - - mCurrentColor = aColor; - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetColor(nscolor &aColor) const -{ - aColor = mCurrentColor; - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::SetFont(const nsFont& aFont, nsIAtom* aLangGroup) -{ - nsCOMPtr newMetrics; - nsresult rv = mContext->GetMetricsFor(aFont, aLangGroup, *getter_AddRefs(newMetrics)); - if (NS_SUCCEEDED(rv)) { - rv = SetFont(newMetrics); - } - return rv; -} - -NS_IMETHODIMP nsRenderingContextGTK::SetFont(nsIFontMetrics *aFontMetrics) -{ - NS_IF_RELEASE(mFontMetrics); - mFontMetrics = NS_REINTERPRET_CAST(nsIFontMetricsGTK *, aFontMetrics); - NS_IF_ADDREF(mFontMetrics); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::SetLineStyle(nsLineStyle aLineStyle) -{ - if (aLineStyle != mCurrentLineStyle) - { - switch(aLineStyle) - { - case nsLineStyle_kSolid: - { - mLineStyle = GDK_LINE_SOLID; - mDashes = 0; - /* ::gdk_gc_set_line_attributes(mSurface->GetGC(), - 1, - GDK_LINE_SOLID, - (GdkCapStyle)0, - (GdkJoinStyle)0); - */ - } - break; - - case nsLineStyle_kDashed: - { - mLineStyle = GDK_LINE_ON_OFF_DASH; - mDashList[0] = mDashList[1] = 4; - mDashes = 2; - - /* ::gdk_gc_set_dashes(mSurface->GetGC(), - 0, dashed, 2); - */ - } - break; - - case nsLineStyle_kDotted: - { - mDashList[0] = mDashList[1] = 1; - mLineStyle = GDK_LINE_ON_OFF_DASH; - mDashes = 2; - - /* ::gdk_gc_set_dashes(mSurface->GetGC(), - 0, dotted, 2); - */ - } - break; - - default: - break; - - } - - mCurrentLineStyle = aLineStyle ; - } - - return NS_OK; - -} - -NS_IMETHODIMP nsRenderingContextGTK::GetLineStyle(nsLineStyle &aLineStyle) -{ - aLineStyle = mCurrentLineStyle; - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetFontMetrics(nsIFontMetrics *&aFontMetrics) -{ - NS_IF_ADDREF(mFontMetrics); - aFontMetrics = mFontMetrics; - return NS_OK; -} - -// add the passed in translation to the current translation -NS_IMETHODIMP nsRenderingContextGTK::Translate(nscoord aX, nscoord aY) -{ - mTranMatrix->AddTranslation((float)aX,(float)aY); - return NS_OK; -} - -// add the passed in scale to the current scale -NS_IMETHODIMP nsRenderingContextGTK::Scale(float aSx, float aSy) -{ - mTranMatrix->AddScale(aSx, aSy); - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::GetCurrentTransform(nsTransform2D *&aTransform) -{ - aTransform = mTranMatrix; - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::CreateDrawingSurface(const nsRect &aBounds, - PRUint32 aSurfFlags, - nsIDrawingSurface* &aSurface) -{ - if (nsnull == mSurface) { - aSurface = nsnull; - return NS_ERROR_FAILURE; - } - - g_return_val_if_fail ((aBounds.width > 0) && (aBounds.height > 0), NS_ERROR_FAILURE); - - nsresult rv = NS_OK; - nsDrawingSurfaceGTK *surf = new nsDrawingSurfaceGTK(); - - if (surf) - { - NS_ADDREF(surf); - PushState(); - mClipRegion = nsnull; - UpdateGC(); - rv = surf->Init(mGC, aBounds.width, aBounds.height, aSurfFlags); - PopState(); - } else { - rv = NS_ERROR_FAILURE; - } - - aSurface = surf; - - return rv; -} - -NS_IMETHODIMP nsRenderingContextGTK::DestroyDrawingSurface(nsIDrawingSurface* aDS) -{ - nsDrawingSurfaceGTK *surf = (nsDrawingSurfaceGTK *) aDS; - - g_return_val_if_fail ((surf != NULL), NS_ERROR_FAILURE); - - NS_IF_RELEASE(surf); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1) -{ - nscoord diffX,diffY; - - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - mTranMatrix->TransformCoord(&aX0,&aY0); - mTranMatrix->TransformCoord(&aX1,&aY1); - - diffX = aX1-aX0; - diffY = aY1-aY0; - - if (0!=diffX) { - diffX = (diffX>0?1:-1); - } - if (0!=diffY) { - diffY = (diffY>0?1:-1); - } - - UpdateGC(); - - ::gdk_draw_line(mSurface->GetDrawable(), - mGC, - aX0, aY0, aX1-diffX, aY1-diffY); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints) -{ - PRInt32 i; - - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - GdkPoint *pts = new GdkPoint[aNumPoints]; - for (i = 0; i < aNumPoints; i++) - { - nsPoint p = aPoints[i]; - mTranMatrix->TransformCoord(&p.x,&p.y); - pts[i].x = p.x; - pts[i].y = p.y; - } - - UpdateGC(); - - ::gdk_draw_lines(mSurface->GetDrawable(), - mGC, - pts, aNumPoints); - - delete[] pts; - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawRect(const nsRect& aRect) -{ - return DrawRect(aRect.x, aRect.y, aRect.width, aRect.height); -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) -{ - if (nsnull == mTranMatrix || nsnull == mSurface) { - return NS_ERROR_FAILURE; - } - - nscoord x,y,w,h; - - x = aX; - y = aY; - w = aWidth; - h = aHeight; - - g_return_val_if_fail ((mSurface->GetDrawable() != NULL) || - (mGC != NULL), NS_ERROR_FAILURE); - - mTranMatrix->TransformCoord(&x,&y,&w,&h); - - // After the transform, if the numbers are huge, chop them, because - // they're going to be converted from 32 bit to 16 bit. - // It's all way off the screen anyway. - ConditionRect(x,y,w,h); - - // Don't draw empty rectangles; also, w/h are adjusted down by one - // so that the right number of pixels are drawn. - if (w && h) { - - UpdateGC(); - - ::gdk_draw_rectangle(mSurface->GetDrawable(), mGC, - FALSE, - x, y, - w - 1, - h - 1); - } - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::FillRect(const nsRect& aRect) -{ - return FillRect(aRect.x, aRect.y, aRect.width, aRect.height); -} - -NS_IMETHODIMP nsRenderingContextGTK::FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) -{ - if (nsnull == mTranMatrix || nsnull == mSurface) { - return NS_ERROR_FAILURE; - } - - nscoord x,y,w,h; - - x = aX; - y = aY; - w = aWidth; - h = aHeight; - - mTranMatrix->TransformCoord(&x,&y,&w,&h); - - // After the transform, if the numbers are huge, chop them, because - // they're going to be converted from 32 bit to 16 bit. - // It's all way off the screen anyway. - ConditionRect(x,y,w,h); - - UpdateGC(); - - ::gdk_draw_rectangle(mSurface->GetDrawable(), mGC, - TRUE, - x, y, w, h); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::InvertRect(const nsRect& aRect) -{ - return InvertRect(aRect.x, aRect.y, aRect.width, aRect.height); -} - -NS_IMETHODIMP nsRenderingContextGTK::InvertRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) -{ - if (nsnull == mTranMatrix || nsnull == mSurface) { - return NS_ERROR_FAILURE; - } - - // Back up the current color, and use GXxor against white to get a - // visible result. - nscolor backupColor = mCurrentColor; - mCurrentColor = NS_RGB(255, 255, 255); - nscoord x,y,w,h; - - x = aX; - y = aY; - w = aWidth; - h = aHeight; - - mTranMatrix->TransformCoord(&x,&y,&w,&h); - - // After the transform, if the numbers are huge, chop them, because - // they're going to be converted from 32 bit to 16 bit. - // It's all way off the screen anyway. - ConditionRect(x,y,w,h); - - mFunction = GDK_XOR; - - UpdateGC(); - - // Fill the rect - ::gdk_draw_rectangle(mSurface->GetDrawable(), mGC, - TRUE, - x, y, w, h); - - // Back to normal copy drawing mode - mFunction = GDK_COPY; - - // Restore current color - mCurrentColor = backupColor; - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawPolygon(const nsPoint aPoints[], PRInt32 aNumPoints) -{ - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - GdkPoint *pts = new GdkPoint[aNumPoints]; - for (PRInt32 i = 0; i < aNumPoints; i++) - { - nsPoint p = aPoints[i]; - mTranMatrix->TransformCoord(&p.x,&p.y); - pts[i].x = p.x; - pts[i].y = p.y; - } - - UpdateGC(); - - ::gdk_draw_polygon(mSurface->GetDrawable(), mGC, FALSE, pts, aNumPoints); - - delete[] pts; - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::FillPolygon(const nsPoint aPoints[], PRInt32 aNumPoints) -{ - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - GdkPoint *pts = new GdkPoint[aNumPoints]; - for (PRInt32 i = 0; i < aNumPoints; i++) - { - nsPoint p = aPoints[i]; - mTranMatrix->TransformCoord(&p.x,&p.y); - pts[i].x = p.x; - pts[i].y = p.y; - } - - UpdateGC(); - - ::gdk_draw_polygon(mSurface->GetDrawable(), mGC, TRUE, pts, aNumPoints); - - delete[] pts; - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawEllipse(const nsRect& aRect) -{ - return DrawEllipse(aRect.x, aRect.y, aRect.width, aRect.height); -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) -{ - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - nscoord x,y,w,h; - - x = aX; - y = aY; - w = aWidth; - h = aHeight; - - mTranMatrix->TransformCoord(&x,&y,&w,&h); - - UpdateGC(); - - ::gdk_draw_arc(mSurface->GetDrawable(), mGC, FALSE, - x, y, w, h, - 0, 360 * 64); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::FillEllipse(const nsRect& aRect) -{ - return FillEllipse(aRect.x, aRect.y, aRect.width, aRect.height); -} - -NS_IMETHODIMP nsRenderingContextGTK::FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) -{ - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - nscoord x,y,w,h; - - x = aX; - y = aY; - w = aWidth; - h = aHeight; - - mTranMatrix->TransformCoord(&x,&y,&w,&h); - - UpdateGC(); - - if (w < 16 || h < 16) { - /* Fix for bug 91816 ("bullets are not displayed correctly on certain text zooms") - * De-uglify bullets on some X servers: - * 1st: Draw... */ - ::gdk_draw_arc(mSurface->GetDrawable(), mGC, FALSE, - x, y, w, h, - 0, 360 * 64); - /* ...then fill. */ - } - ::gdk_draw_arc(mSurface->GetDrawable(), mGC, TRUE, - x, y, w, h, - 0, 360 * 64); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawArc(const nsRect& aRect, - float aStartAngle, float aEndAngle) -{ - return DrawArc(aRect.x,aRect.y,aRect.width,aRect.height,aStartAngle,aEndAngle); -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawArc(nscoord aX, nscoord aY, - nscoord aWidth, nscoord aHeight, - float aStartAngle, float aEndAngle) -{ - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - nscoord x,y,w,h; - - x = aX; - y = aY; - w = aWidth; - h = aHeight; - - mTranMatrix->TransformCoord(&x,&y,&w,&h); - - UpdateGC(); - - ::gdk_draw_arc(mSurface->GetDrawable(), mGC, FALSE, - x, y, w, h, - NSToIntRound(aStartAngle * 64.0f), - NSToIntRound(aEndAngle * 64.0f)); - - return NS_OK; -} - -NS_IMETHODIMP nsRenderingContextGTK::FillArc(const nsRect& aRect, - float aStartAngle, float aEndAngle) -{ - return FillArc(aRect.x,aRect.y,aRect.width,aRect.height,aStartAngle,aEndAngle); -} - - -NS_IMETHODIMP nsRenderingContextGTK::FillArc(nscoord aX, nscoord aY, - nscoord aWidth, nscoord aHeight, - float aStartAngle, float aEndAngle) -{ - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - - nscoord x,y,w,h; - - x = aX; - y = aY; - w = aWidth; - h = aHeight; - - mTranMatrix->TransformCoord(&x,&y,&w,&h); - - UpdateGC(); - - ::gdk_draw_arc(mSurface->GetDrawable(), mGC, TRUE, - x, y, w, h, - NSToIntRound(aStartAngle * 64.0f), - NSToIntRound(aEndAngle * 64.0f)); - - return NS_OK; -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetWidth(char aC, nscoord &aWidth) -{ - // Check for the very common case of trying to get the width of a single - // space. - if ((aC == ' ') && (nsnull != mFontMetrics)) { - return mFontMetrics->GetSpaceWidth(aWidth); - } - return GetWidth(&aC, 1, aWidth); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetWidth(PRUnichar aC, nscoord& aWidth, - PRInt32* aFontID) -{ - return GetWidth(&aC, 1, aWidth, aFontID); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetWidthInternal(const char* aString, PRUint32 aLength, - nscoord& aWidth) -{ - if (0 == aLength) { - aWidth = 0; - return NS_OK; - } - - g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE); - - return mFontMetrics->GetWidth(aString, aLength, aWidth, this); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetWidthInternal(const PRUnichar* aString, PRUint32 aLength, - nscoord& aWidth, PRInt32* aFontID) -{ - if (0 == aLength) { - aWidth = 0; - return NS_OK; - } - - g_return_val_if_fail(aString != NULL, NS_ERROR_FAILURE); - - return mFontMetrics->GetWidth(aString, aLength, aWidth, aFontID, this); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensionsInternal(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions) -{ - mFontMetrics->GetMaxAscent(aDimensions.ascent); - mFontMetrics->GetMaxDescent(aDimensions.descent); - return GetWidth(aString, aLength, aDimensions.width); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensionsInternal(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID) -{ - return mFontMetrics->GetTextDimensions(aString, aLength, aDimensions, - aFontID, this); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensionsInternal(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) -{ - return mFontMetrics->GetTextDimensions(aString, aLength, aAvailWidth, - aBreaks, aNumBreaks, aDimensions, - aNumCharsFit, - aLastWordDimensions, aFontID, - this); -} -NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensionsInternal(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) -{ - return mFontMetrics->GetTextDimensions(aString, aLength, aAvailWidth, - aBreaks, aNumBreaks, aDimensions, - aNumCharsFit, - aLastWordDimensions, aFontID, - this); -} - -NS_IMETHODIMP -nsRenderingContextGTK::DrawStringInternal(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing) -{ - return mFontMetrics->DrawString(aString, aLength, aX, aY, aSpacing, - this, mSurface); -} - -NS_IMETHODIMP -nsRenderingContextGTK::DrawStringInternal(const PRUnichar* aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) -{ - return mFontMetrics->DrawString(aString, aLength, aX, aY, aFontID, - aSpacing, this, mSurface); -} - -NS_IMETHODIMP -nsRenderingContextGTK::CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, - PRInt32 aSrcX, PRInt32 aSrcY, - const nsRect &aDestBounds, - PRUint32 aCopyFlags) -{ - PRInt32 srcX = aSrcX; - PRInt32 srcY = aSrcY; - nsRect drect = aDestBounds; - nsDrawingSurfaceGTK *destsurf; - - g_return_val_if_fail(aSrcSurf != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mTranMatrix != NULL, NS_ERROR_FAILURE); - g_return_val_if_fail(mSurface != NULL, NS_ERROR_FAILURE); - -#if 0 - printf("nsRenderingContextGTK::CopyOffScreenBits()\nflags=\n"); - - if (aCopyFlags & NS_COPYBITS_USE_SOURCE_CLIP_REGION) - printf("NS_COPYBITS_USE_SOURCE_CLIP_REGION\n"); - - if (aCopyFlags & NS_COPYBITS_XFORM_SOURCE_VALUES) - printf("NS_COPYBITS_XFORM_SOURCE_VALUES\n"); - - if (aCopyFlags & NS_COPYBITS_XFORM_DEST_VALUES) - printf("NS_COPYBITS_XFORM_DEST_VALUES\n"); - - if (aCopyFlags & NS_COPYBITS_TO_BACK_BUFFER) - printf("NS_COPYBITS_TO_BACK_BUFFER\n"); - - printf("\n"); -#endif - - if (aCopyFlags & NS_COPYBITS_TO_BACK_BUFFER) - { - NS_ASSERTION(!(nsnull == mSurface), "no back buffer"); - destsurf = mSurface; - } - else - { - NS_ENSURE_TRUE(mOffscreenSurface != nsnull, NS_ERROR_FAILURE); - destsurf = mOffscreenSurface; - } - - if (aCopyFlags & NS_COPYBITS_XFORM_SOURCE_VALUES) - mTranMatrix->TransformCoord(&srcX, &srcY); - - if (aCopyFlags & NS_COPYBITS_XFORM_DEST_VALUES) - mTranMatrix->TransformCoord(&drect.x, &drect.y, &drect.width, &drect.height); - -#if 0 - // XXX implement me - if (aCopyFlags & NS_COPYBITS_USE_SOURCE_CLIP_REGION) - { - // we should use the source clip region if this flag is used... - nsIRegion *region; - CopyClipRegion(); - } -#endif - - //XXX flags are unused. that would seem to mean that there is - //inefficiency somewhere... MMP - - // gdk_draw_pixmap and copy_area do the same thing internally. - // copy_area sounds better - - UpdateGC(); - - ::gdk_window_copy_area(destsurf->GetDrawable(), - mGC, - drect.x, drect.y, - ((nsDrawingSurfaceGTK *)aSrcSurf)->GetDrawable(), - srcX, srcY, - drect.width, drect.height); - - - return NS_OK; -} - -#ifdef MOZ_MATHML - -NS_IMETHODIMP -nsRenderingContextGTK::GetBoundingMetricsInternal(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - return mFontMetrics->GetBoundingMetrics(aString, aLength, aBoundingMetrics, - this); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetBoundingMetricsInternal(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID) -{ - return mFontMetrics->GetBoundingMetrics(aString, aLength, aBoundingMetrics, - aFontID, this); -} - -#endif /* MOZ_MATHML */ - -NS_IMETHODIMP nsRenderingContextGTK::SetRightToLeftText(PRBool aIsRTL) -{ - return mFontMetrics->SetRightToLeftText(aIsRTL); -} - -NS_IMETHODIMP nsRenderingContextGTK::GetRightToLeftText(PRBool* aIsRTL) -{ - *aIsRTL = mFontMetrics->GetRightToLeftText(); - return NS_OK; -} - -PRInt32 nsRenderingContextGTK::GetMaxStringLength() -{ - if (!mFontMetrics) - return 1; - return mFontMetrics->GetMaxStringLength(); -} - -NS_IMETHODIMP nsRenderingContextGTK::GetClusterInfo(const PRUnichar *aText, - PRUint32 aLength, - PRUint8 *aClusterStarts) -{ - return mFontMetrics->GetClusterInfo(aText, aLength, aClusterStarts); -} - -PRInt32 nsRenderingContextGTK::GetPosition(const PRUnichar *aText, PRUint32 aLength, - nsPoint aPt) -{ - return mFontMetrics->GetPosition(aText, aLength, aPt); -} - -NS_IMETHODIMP nsRenderingContextGTK::GetRangeWidth(const PRUnichar *aText, PRUint32 aLength, - PRUint32 aStart, PRUint32 aEnd, - PRUint32 &aWidth) -{ - return mFontMetrics->GetRangeWidth(aText, aLength, aStart, aEnd, aWidth); -} - -NS_IMETHODIMP nsRenderingContextGTK::GetRangeWidth(const char *aText, PRUint32 aLength, - PRUint32 aStart, PRUint32 aEnd, - PRUint32 &aWidth) -{ - return mFontMetrics->GetRangeWidth(aText, aLength, aStart, aEnd, aWidth); -} - -NS_IMETHODIMP nsRenderingContextGTK::DrawImage(imgIContainer *aImage, const nsRect & aSrcRect, const nsRect & aDestRect) -{ - UpdateGC(); - return nsRenderingContextImpl::DrawImage(aImage, aSrcRect, aDestRect); -} diff --git a/gfx/src/gtk/nsRenderingContextGTK.h b/gfx/src/gtk/nsRenderingContextGTK.h deleted file mode 100644 index d41dd15a8021..000000000000 --- a/gfx/src/gtk/nsRenderingContextGTK.h +++ /dev/null @@ -1,308 +0,0 @@ -/* -*- Mode: C++; tab-width: 1; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsRenderingContextGTK_h___ -#define nsRenderingContextGTK_h___ - -#include "nsRenderingContextImpl.h" -#include "nsUnitConversion.h" -#include "nsFont.h" -#include "nsPoint.h" -#include "nsString.h" -#include "nsCRT.h" -#include "nsTransform2D.h" -#include "nsIWidget.h" -#include "nsRect.h" -#include "nsIDeviceContext.h" -#include "nsVoidArray.h" -#include "nsGfxCIID.h" -#include "nsDrawingSurfaceGTK.h" -#include "nsRegionGTK.h" -#include "nsIFontMetricsGTK.h" - -#include - -class nsRenderingContextGTK : public nsRenderingContextImpl -{ -public: - nsRenderingContextGTK(); - virtual ~nsRenderingContextGTK(); - static nsresult Shutdown(); // release statics - - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - NS_DECL_ISUPPORTS - - NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWindow); - NS_IMETHOD Init(nsIDeviceContext* aContext, nsIDrawingSurface* aSurface); - - NS_IMETHOD Reset(void); - - NS_IMETHOD GetDeviceContext(nsIDeviceContext *&aContext); - - NS_IMETHOD LockDrawingSurface(PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight, - void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes, - PRUint32 aFlags); - NS_IMETHOD UnlockDrawingSurface(void); - - NS_IMETHOD SelectOffScreenDrawingSurface(nsIDrawingSurface* aSurface); - NS_IMETHOD GetDrawingSurface(nsIDrawingSurface* *aSurface); - NS_IMETHOD GetHints(PRUint32& aResult); - virtual void* GetNativeGraphicData(GraphicDataType aType); - -#if 0 - NS_IMETHOD PushState(PRInt32 aFlags); -#endif - NS_IMETHOD PushState(void); - NS_IMETHOD PopState(void); - - NS_IMETHOD IsVisibleRect(const nsRect& aRect, PRBool &aVisible); - - NS_IMETHOD SetClipRect(const nsRect& aRect, nsClipCombine aCombine); - NS_IMETHOD GetClipRect(nsRect &aRect, PRBool &aClipValid); - NS_IMETHOD SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine); - NS_IMETHOD CopyClipRegion(nsIRegion &aRegion); - NS_IMETHOD GetClipRegion(nsIRegion **aRegion); - - NS_IMETHOD SetLineStyle(nsLineStyle aLineStyle); - NS_IMETHOD GetLineStyle(nsLineStyle &aLineStyle); - - NS_IMETHOD SetColor(nscolor aColor); - NS_IMETHOD GetColor(nscolor &aColor) const; - - NS_IMETHOD SetFont(const nsFont& aFont, nsIAtom* aLangGroup); - NS_IMETHOD SetFont(nsIFontMetrics *aFontMetrics); - - NS_IMETHOD GetFontMetrics(nsIFontMetrics *&aFontMetrics); - - NS_IMETHOD Translate(nscoord aX, nscoord aY); - NS_IMETHOD Scale(float aSx, float aSy); - NS_IMETHOD GetCurrentTransform(nsTransform2D *&aTransform); - - NS_IMETHOD CreateDrawingSurface(const nsRect& aBounds, PRUint32 aSurfFlags, nsIDrawingSurface* &aSurface); - NS_IMETHOD DestroyDrawingSurface(nsIDrawingSurface* aDS); - - NS_IMETHOD DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1); - NS_IMETHOD DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints); - - NS_IMETHOD DrawRect(const nsRect& aRect); - NS_IMETHOD DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD FillRect(const nsRect& aRect); - NS_IMETHOD FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD InvertRect(const nsRect& aRect); - NS_IMETHOD InvertRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD DrawPolygon(const nsPoint aPoints[], PRInt32 aNumPoints); - NS_IMETHOD FillPolygon(const nsPoint aPoints[], PRInt32 aNumPoints); - - NS_IMETHOD DrawEllipse(const nsRect& aRect); - NS_IMETHOD DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - NS_IMETHOD FillEllipse(const nsRect& aRect); - NS_IMETHOD FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD DrawArc(const nsRect& aRect, - float aStartAngle, float aEndAngle); - NS_IMETHOD DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, - float aStartAngle, float aEndAngle); - NS_IMETHOD FillArc(const nsRect& aRect, - float aStartAngle, float aEndAngle); - NS_IMETHOD FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, - float aStartAngle, float aEndAngle); - - NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, - PRInt32 *aFontID = nsnull) - { return nsRenderingContextImpl::GetWidth(aString, aWidth, aFontID); } - NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth) - { return nsRenderingContextImpl::GetWidth(aString, aWidth); } - NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, - nscoord& aWidth) - { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth); } - NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, - nscoord &aWidth, PRInt32 *aFontID = nsnull) - { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth, aFontID); } - NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, - PRInt32 aFontID = -1, - const nscoord* aSpacing = nsnull) - { return nsRenderingContextImpl::DrawString(aString, aX, aY, aFontID, aSpacing); } - - NS_IMETHOD GetWidth(char aC, nscoord &aWidth); - NS_IMETHOD GetWidth(PRUnichar aC, nscoord &aWidth, - PRInt32 *aFontID); - - NS_IMETHOD GetWidthInternal(const char *aString, PRUint32 aLength, nscoord &aWidth); - NS_IMETHOD GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, - PRInt32 *aFontID); - - NS_IMETHOD DrawStringInternal(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing); - NS_IMETHOD DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); - - NS_IMETHOD GetTextDimensionsInternal(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions); - NS_IMETHOD GetTextDimensionsInternal(const PRUnichar *aString, PRUint32 aLength, - nsTextDimensions& aDimensions,PRInt32 *aFontID); - NS_IMETHOD GetTextDimensionsInternal(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID); - NS_IMETHOD GetTextDimensionsInternal(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID); - -#ifdef MOZ_MATHML - /** - * Returns metrics (in app units) of an 8-bit character string - */ - NS_IMETHOD GetBoundingMetricsInternal(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); - - /** - * Returns metrics (in app units) of a Unicode character string - */ - NS_IMETHOD GetBoundingMetricsInternal(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID = nsnull); - -#endif /* MOZ_MATHML */ - - virtual PRInt32 GetMaxStringLength(); - - NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, - const nsRect &aDestBounds, PRUint32 aCopyFlags); - - NS_IMETHOD SetRightToLeftText(PRBool aIsRTL); - NS_IMETHOD GetRightToLeftText(PRBool* aIsRTL); - NS_IMETHOD GetClusterInfo(const PRUnichar *aText, PRUint32 aLength, - PRUint8 *aClusterStarts); - virtual PRInt32 GetPosition(const PRUnichar *aText, PRUint32 aLength, - nsPoint aPt); - NS_IMETHOD GetRangeWidth(const PRUnichar *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - NS_IMETHOD GetRangeWidth(const char *aText, - PRUint32 aLength, - PRUint32 aStart, - PRUint32 aEnd, - PRUint32 &aWidth); - - NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect & aSrcRect, const nsRect & aDestRect); - - //locals - NS_IMETHOD CommonInit(); - - void CreateClipRegion(); - - GdkGC *GetGC() { - if (!mGC) - UpdateGC(); - return gdk_gc_ref(mGC); - } - - void SetClipRectInPixels(const nsRect& aRect, nsClipCombine aCombine); - - // cause the GC to be updated - void UpdateGC(); - - // Get a pointer to the trans matrix - nsTransform2D *GetTranMatrix() { - return mTranMatrix; - } - -private: - nsDrawingSurfaceGTK *mOffscreenSurface; - nsDrawingSurfaceGTK *mSurface; - nsIDeviceContext *mContext; - nsIFontMetricsGTK *mFontMetrics; - nsCOMPtr mClipRegion; - float mP2T; - GdkWChar* mDrawStringBuf; - PRUint32 mDrawStringSize; - - // graphic state stack (GraphicsState) - nsAutoVoidArray mStateCache; - - GdkGC *mGC; - GdkFunction mFunction; - GdkLineStyle mLineStyle; - char mDashList[2]; - int mDashes; - nscolor mCurrentColor; - nsLineStyle mCurrentLineStyle; - - // ConditionRect is used to fix coordinate overflow problems for - // rectangles after they are transformed to screen coordinates - void ConditionRect(nscoord &x, nscoord &y, nscoord &w, nscoord &h) { - if ( y < -32766 ) { - y = -32766; - } - - if ( y + h > 32766 ) { - h = 32766 - y; - } - - if ( x < -32766 ) { - x = -32766; - } - - if ( x + w > 32766 ) { - w = 32766 - x; - } - } -}; - -#endif /* nsRenderingContextGTK_h___ */ diff --git a/gfx/src/gtk/pangoFontEncoding.properties b/gfx/src/gtk/pangoFontEncoding.properties deleted file mode 100644 index 7b8aa2cca26d..000000000000 --- a/gfx/src/gtk/pangoFontEncoding.properties +++ /dev/null @@ -1,120 +0,0 @@ -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is Mozilla MathML Project. -# -# The Initial Developer of the Original Code is -# The University of Queensland. -# Portions created by the Initial Developer are Copyright (C) 2001 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Roger B. Sidje -# Jungshik Shin -# Christopher Blizzard -# -# 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 -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -# LOCALIZATION NOTE: FILE -# Do not translate anything in this file - -# This file contains supported custom encodings for pango font -# rendering. For information about the specific encodings, look at -# fontEncoding.properties. It contains a lot more verbiage than you -# will find here. There are a lot of encodings supported in the old -# encoding file that pango supports directly, so there should be -# little reason to use those custom encodings. The pango custom code -# doesn't support .wide fonts, so consider yourself warned! -# - -# To be honest, we basically support mathml and that's about it. - -encoding.cmr10.ttf = x-ttf-cmr -encoding.cmmi10.ttf = x-ttf-cmmi -encoding.cmsy10.ttf = x-ttf-cmsy -encoding.cmex10.ttf = x-ttf-cmex - -encoding.cmr10.ftcmap = unicode -encoding.cmmi10.ftcmap = unicode -encoding.cmsy10.ftcmap = unicode -encoding.cmex10.ftcmap = unicode - -encoding.math1.ttf = x-mathematica1 -encoding.math1-bold.ttf = x-mathematica1 -encoding.math1mono.ttf = x-mathematica1 -encoding.math1mono-bold.ttf = x-mathematica1 - -encoding.math2.ttf = x-mathematica2 -encoding.math2-bold.ttf = x-mathematica2 -encoding.math2mono.ttf = x-mathematica2 -encoding.math2mono-bold.ttf = x-mathematica2 - -encoding.math3.ttf = x-mathematica3 -encoding.math3-bold.ttf = x-mathematica3 -encoding.math3mono.ttf = x-mathematica3 -encoding.math3mono-bold.ttf = x-mathematica3 - -encoding.math4.ttf = x-mathematica4 -encoding.math4-bold.ttf = x-mathematica4 -encoding.math4mono.ttf = x-mathematica4 -encoding.math4mono-bold.ttf = x-mathematica4 - -encoding.math5.ttf = x-mathematica5 -encoding.math5-bold.ttf = x-mathematica5 -encoding.math5bold.ttf = x-mathematica5 -encoding.math5mono.ttf = x-mathematica5 -encoding.math5mono-bold.ttf = x-mathematica5 -encoding.math5monobold.ttf = x-mathematica5 - -encoding.math1.ftcmap = mac_roman -encoding.math1-bold.ftcmap = mac_roman -encoding.math1mono.ftcmap = mac_roman -encoding.math1mono-bold.ftcmap = mac_roman - -encoding.math2.ftcmap = mac_roman -encoding.math2-bold.ftcmap = mac_roman -encoding.math2mono.ftcmap = mac_roman -encoding.math2mono-bold.ftcmap = mac_roman - -encoding.math3.ftcmap = mac_roman -encoding.math3-bold.ftcmap = mac_roman -encoding.math3mono.ftcmap = mac_roman -encoding.math3mono-bold.ftcmap = mac_roman - -encoding.math4.ftcmap = mac_roman -encoding.math4-bold.ftcmap = mac_roman -encoding.math4mono.ftcmap = mac_roman -encoding.math4mono-bold.ftcmap = mac_roman - -encoding.math5.ftcmap = mac_roman -encoding.math5-bold.ftcmap = mac_roman -encoding.math5bold.ftcmap = mac_roman -encoding.math5mono.ftcmap = mac_roman -encoding.math5mono-bold.ftcmap = mac_roman -encoding.math5monobold.ftcmap = mac_roman - -encoding.mtextra.ttf = x-mtextra -encoding.mtextra.ftcmap = mac_roman - diff --git a/gfx/src/gtk/xregion.h b/gfx/src/gtk/xregion.h deleted file mode 100644 index 1d6207f90609..000000000000 --- a/gfx/src/gtk/xregion.h +++ /dev/null @@ -1,177 +0,0 @@ -/* $XConsortium: region.h,v 11.13 91/09/10 08:21:49 rws Exp $ */ -/************************************************************************ -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, -and the Massachusetts Institute of Technology, Cambridge, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Digital or MIT not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ - -#ifndef _XREGION_H -#define _XREGION_H - -typedef struct { - short x1, x2, y1, y2; -} Box, BOX, BoxRec, *BoxPtr; - -typedef struct { - short x, y, width, height; -}RECTANGLE, RectangleRec, *RectanglePtr; - -#ifdef TRUE -#undef TRUE -#endif - -#define TRUE 1 -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef MAXSHORT -#define MAXSHORT 32767 -#endif -#ifndef MINSHORT -#define MINSHORT -MAXSHORT -#endif -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - - -/* - * clip region - */ - -typedef struct _XRegion { - long size; - long numRects; - BOX *rects; - BOX extents; -} REGION; - -/* Xutil.h contains the declaration: - * typedef struct _XRegion *Region; - */ - -/* 1 if two BOXs overlap. - * 0 if two BOXs do not overlap. - * Remember, x2 and y2 are not in the region - */ -#define EXTENTCHECK(r1, r2) \ - ((r1)->x2 > (r2)->x1 && \ - (r1)->x1 < (r2)->x2 && \ - (r1)->y2 > (r2)->y1 && \ - (r1)->y1 < (r2)->y2) - -/* - * update region extents - */ -#define EXTENTS(r,idRect){\ - if((r)->x1 < (idRect)->extents.x1)\ - (idRect)->extents.x1 = (r)->x1;\ - if((r)->y1 < (idRect)->extents.y1)\ - (idRect)->extents.y1 = (r)->y1;\ - if((r)->x2 > (idRect)->extents.x2)\ - (idRect)->extents.x2 = (r)->x2;\ - if((r)->y2 > (idRect)->extents.y2)\ - (idRect)->extents.y2 = (r)->y2;\ - } - -/* - * Check to see if there is enough memory in the present region. - */ -#define MEMCHECK(reg, rect, firstrect){\ - if ((reg)->numRects >= ((reg)->size - 1)){\ - (firstrect) = (BOX *) Xrealloc \ - ((char *)(firstrect), (unsigned) (2 * (sizeof(BOX)) * ((reg)->size)));\ - if ((firstrect) == 0)\ - return(0);\ - (reg)->size *= 2;\ - (rect) = &(firstrect)[(reg)->numRects];\ - }\ - } - -/* this routine checks to see if the previous rectangle is the same - * or subsumes the new rectangle to add. - */ - -#define CHECK_PREVIOUS(Reg, R, Rx1, Ry1, Rx2, Ry2)\ - (!(((Reg)->numRects > 0)&&\ - ((R-1)->y1 == (Ry1)) &&\ - ((R-1)->y2 == (Ry2)) &&\ - ((R-1)->x1 <= (Rx1)) &&\ - ((R-1)->x2 >= (Rx2)))) - -/* add a rectangle to the given Region */ -#define ADDRECT(reg, r, rx1, ry1, rx2, ry2){\ - if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&\ - CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\ - (r)->x1 = (rx1);\ - (r)->y1 = (ry1);\ - (r)->x2 = (rx2);\ - (r)->y2 = (ry2);\ - EXTENTS((r), (reg));\ - (reg)->numRects++;\ - (r)++;\ - }\ - } - - - -/* add a rectangle to the given Region */ -#define ADDRECTNOX(reg, r, rx1, ry1, rx2, ry2){\ - if ((rx1 < rx2) && (ry1 < ry2) &&\ - CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\ - (r)->x1 = (rx1);\ - (r)->y1 = (ry1);\ - (r)->x2 = (rx2);\ - (r)->y2 = (ry2);\ - (reg)->numRects++;\ - (r)++;\ - }\ - } - -#define EMPTY_REGION(pReg) pReg->numRects = 0 - -#define REGION_NOT_EMPTY(pReg) pReg->numRects - -#define INBOX(r, x, y) \ - ( ( ((r).x2 > x)) && \ - ( ((r).x1 <= x)) && \ - ( ((r).y2 > y)) && \ - ( ((r).y1 <= y)) ) - -/* - * number of points to buffer before sending them off - * to scanlines() : Must be an even number - */ -#define NUMPTSTOBUFFER 200 - -/* - * used to allocate buffers for points and link - * the buffers together - */ -typedef struct _POINTBLOCK { - XPoint pts[NUMPTSTOBUFFER]; - struct _POINTBLOCK *next; -} POINTBLOCK; - -#endif diff --git a/gfx/src/x11shared/README b/gfx/src/x11shared/README deleted file mode 100644 index 5b3926ff0cc3..000000000000 --- a/gfx/src/x11shared/README +++ /dev/null @@ -1,6 +0,0 @@ -This dir, x11shared, is for code common to multiple X11 -implementations (eg: gtk, xlib, xprint). - -Code that is being (or would be) *replicated* in several -of these should be factored out and put here. - diff --git a/gfx/src/x11shared/dbyte_special_chars.ccmap b/gfx/src/x11shared/dbyte_special_chars.ccmap deleted file mode 100755 index f85642cab7d9..000000000000 --- a/gfx/src/x11shared/dbyte_special_chars.ccmap +++ /dev/null @@ -1,178 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Jungshik Shin - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - /*======================================================== - This file contains a precompiled CCMap for a class of Unicode - characters (dbyte_special_chars) to be identified quickly by Mozilla. - It was generated by ccmapbin.pl which you can find under - mozilla/intl/unicharutil/tools. - - Enumerated below are characters included in the precompiled CCMap - which is human-readable but not so human-friendly. If you - needs to modify the list of characters belonging to "dbyte_special_chars", - you have to make a new file (with the name of your choice) - listing characters (one character per line) you want to put - into "dbyte_special_chars" in the format - - 0xuuuu // comment - - In addition, the input file can have the following optional lines that - read - - VARIABLE::gDoubleByteSpecialCharsCCMap - CLASS::dbyte_special_chars - DESCRIPTION:: description of a character class - FILE:: mozilla source file to include the output file - - - Then, run the following in the current directory. - - perl ccmapbin.pl input_file [gDoubleByteSpecialCharsCCMap [dbyte_special_chars]] - - which will generate dbyte_special_chars.ccmap (or dbyte_special_chars.x-ccmap if the ccmap - includes non-BMP characters.). gDoubleByteSpecialCharsCCMap is used as the prefix - in macros for the array initializer and the array size. - - (see bug 180266, bug 167136, and bug 224337) - - */ - - -/* - VARIABLE:: gDoubleByteSpecialCharsCCMap - CLASS:: dbyte_special_chars - DESCRIPTION:: description of a character class - FILE:: mozilla source file to include output files - - 0X000152 : LATIN CAPITAL LIGATURE OE - 0X000153 : LATIN SMALL LIGATURE OE - 0X000160 : LATIN CAPITAL LETTER S WITH CARON - 0X000161 : LATIN SMALL LETTER S WITH CARON - 0X000178 : LATIN CAPITAL LETTER Y WITH DIAERESIS - 0X00017D : LATIN CAPITAL LETTER Z WITH CARON - 0X00017E : LATIN SMALL LETTER Z WITH CARON - 0X000192 : LATIN SMALL LETTER F WITH HOOK - 0X0002C6 : MODIFIER LETTER CIRCUMFLEX ACCENT - 0X0002DC : SMALL TILDE - 0X002013 : EN DASH - 0X002018 : LEFT SINGLE QUOTATION MARK - 0X002019 : RIGHT SINGLE QUOTATION MARK - 0X00201A : SINGLE LOW-9 QUOTATION MARK - 0X00201C : LEFT DOUBLE QUOTATION MARK - 0X00201D : RIGHT DOUBLE QUOTATION MARK - 0X00201E : DOUBLE LOW-9 QUOTATION MARK - 0X002020 : DAGGER - 0X002021 : DOUBLE DAGGER - 0X002022 : BULLET - 0X002026 : HORIZONTAL ELLIPSIS - 0X002030 : PER MILLE SIGN - 0X002039 : SINGLE LEFT-POINTING ANGLE QUOTATION MARK - 0X00203A : SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - 0X0020AC : EURO SIGN - 0X002122 : TRADE MARK SIGN -*/ - -#if (defined(IS_LITTLE_ENDIAN) || ALU_SIZE == 16) -// Precompiled CCMap for Little Endian(16/32/64bit) -// and Big Endian(16bit) -#define gDoubleByteSpecialCharsCCMap_SIZE 144 -#define gDoubleByteSpecialCharsCCMap_INITIALIZER \ -/* 000000 */ 0x0030,0x0010,0x0060,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0020,0x0040,0x0050,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000040 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x000C,0x0003,0x6100, \ - 0x0000,0x0004,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0040,0x1000,0x0000,0x0000, \ -/* 000060 */ 0x0070,0x0080,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000070 */ 0x0000,0x7708,0x0047,0x0601,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000080 */ 0x0000,0x0000,0x0004,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#elif (ALU_SIZE == 32) -// Precompiled CCMap for Big Endian(32bit) -#define gDoubleByteSpecialCharsCCMap_SIZE 144 -#define gDoubleByteSpecialCharsCCMap_INITIALIZER \ -/* 000000 */ 0x0030,0x0010,0x0060,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0020,0x0040,0x0050,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000040 */ 0x0000,0x0000,0x0000,0x0000,0x000C,0x0000,0x6100,0x0003, \ - 0x0004,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x1000,0x0040,0x0000,0x0000, \ -/* 000060 */ 0x0070,0x0080,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000070 */ 0x7708,0x0000,0x0601,0x0047,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x1000,0x0000,0x0000,0x0000,0x0000, \ -/* 000080 */ 0x0000,0x0000,0x0000,0x0004,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#elif (ALU_SIZE == 64) -// Precompiled CCMap for Big Endian(64bit) -#define gDoubleByteSpecialCharsCCMap_SIZE 144 -#define gDoubleByteSpecialCharsCCMap_INITIALIZER \ -/* 000000 */ 0x0030,0x0010,0x0060,0x0010,0x0010,0x0010,0x0010,0x0010, \ - 0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010, \ -/* 000010 */ 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000020 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000030 */ 0x0020,0x0040,0x0050,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000040 */ 0x0000,0x0000,0x0000,0x0000,0x6100,0x0003,0x000C,0x0000, \ - 0x0000,0x0000,0x0004,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000050 */ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x0040, \ -/* 000060 */ 0x0070,0x0080,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ - 0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020, \ -/* 000070 */ 0x0601,0x0047,0x7708,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ -/* 000080 */ 0x0000,0x0004,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, \ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -#else -#error "We don't support this architecture." -#endif - diff --git a/gfx/src/x11shared/nsAntiAliasedGlyph.cpp b/gfx/src/x11shared/nsAntiAliasedGlyph.cpp deleted file mode 100644 index 6d9900fd1bde..000000000000 --- a/gfx/src/x11shared/nsAntiAliasedGlyph.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "gfx-config.h" -#include -#include -#include -#include -#include "nsCRT.h" - -#include "nsAntiAliasedGlyph.h" - -nsAntiAliasedGlyph::nsAntiAliasedGlyph(PRUint32 aMaxWidth, PRUint32 aMaxHeight, - PRUint32 aBorder) -{ - mMaxWidth = aMaxWidth; - mMaxHeight = aMaxHeight; - mBorder = aBorder; - mBufferWidth = mBorder + mMaxWidth + mBorder; - mBufferHeight = mBorder + mMaxHeight + mBorder; - - mAscent = 0; - mDescent = 0; - mLBearing = 0; - mRBearing = 0; - mWidth = 0; - mHeight = 0; - mAdvance = 0; - mOwnBuffer = PR_FALSE; - mBuffer = nsnull; - mBufferLen = 0; -} - -nsAntiAliasedGlyph::~nsAntiAliasedGlyph() -{ - if (mOwnBuffer) - nsMemory::Free(mBuffer); -} - -PRBool -nsAntiAliasedGlyph::Init() -{ - return Init(nsnull, 0); -} - -PRBool -nsAntiAliasedGlyph::Init(PRUint8 *aBuffer, PRUint32 aBufferLen) -{ - mBufferLen = mBufferWidth * mBufferHeight; - if (aBufferLen >= mBufferLen) { - mBuffer = aBuffer; - mOwnBuffer = PR_FALSE; - } - else { - mBuffer = (PRUint8 *)nsMemory::Alloc(mBufferLen); - if (!mBuffer) { - mBufferLen = 0; - return PR_FALSE; - } - mOwnBuffer = PR_TRUE; - } - memset(mBuffer, 0, mBufferLen); - return PR_TRUE; -} - -#ifdef MOZ_ENABLE_FREETYPE2 -PRBool -nsAntiAliasedGlyph::WrapFreeType(FT_BBox *aBbox, FT_BitmapGlyph aSlot, - PRUint8 *aBuffer, PRUint32 aBufferLen) -{ - mAscent = aBbox->yMax; - mDescent = aBbox->yMin; - mLBearing = aBbox->xMin; - mRBearing = aBbox->xMax; - mAdvance = aSlot->root.advance.x>>16; - mWidth = aSlot->bitmap.width; - mHeight = aSlot->bitmap.rows; - - - if (aSlot->bitmap.pixel_mode == ft_pixel_mode_grays) { - mBufferWidth = aSlot->bitmap.pitch; - mBufferHeight = aSlot->bitmap.rows; - mBufferLen = mBufferWidth * mBufferHeight; - mBuffer = aSlot->bitmap.buffer; - mOwnBuffer = PR_FALSE; - return PR_TRUE; - } - else { - // expand the data from 1 bit to 8 bit - mBufferWidth = aSlot->bitmap.width; - mBufferHeight = aSlot->bitmap.rows; - if (!Init(aBuffer, aBufferLen)) - return PR_FALSE; - int pitch = aSlot->bitmap.pitch; - for (int row=0; rowbitmap.rows; row++) { - for (int j=0; jbitmap.width; j++) { - int byte = aSlot->bitmap.buffer[(j>>3) + (row*pitch)]; - if (!((byte<<(j&0x7)) & 0x80)) - continue; - mBuffer[j+(row*mBufferWidth)] = 255; - } - } - } - return PR_TRUE; -} -#endif - -PRBool -nsAntiAliasedGlyph::SetImage(XCharStruct *aCharStruct, XImage *aXImage) -{ - NS_ASSERTION(mBuffer, "null buffer (was Init called?)"); - if (!mBuffer) - return PR_FALSE; - PRUint32 src_width = GLYPH_RIGHT_EDGE(aCharStruct) - - GLYPH_LEFT_EDGE(aCharStruct); - PRUint32 src_height = aXImage->height; - if ((src_width > mMaxWidth) || (src_height > mMaxHeight)) { - NS_ASSERTION(src_width<=mMaxWidth,"unexpected width"); - NS_ASSERTION(src_height<=mMaxHeight,"unexpected height"); - return PR_FALSE; - } - - mAscent = aCharStruct->ascent; - mDescent = aCharStruct->descent; - mLBearing = aCharStruct->lbearing; - mRBearing = aCharStruct->rbearing; - mWidth = src_width; - mHeight = src_height; - mAdvance = aCharStruct->width; - - NS_ASSERTION(aXImage->format==ZPixmap,"unexpected image format"); - if (aXImage->format != ZPixmap) - return PR_FALSE; - - int bits_per_pixel = aXImage->bits_per_pixel; - memset((char*)mBuffer, 0, mBufferLen); - - PRUint32 x, y; - PRUint32 src_index = 0; - PRUint32 dst_index = mBorder + (mBorder*mBufferWidth); - PRInt32 delta_dst_row = -src_width + mBufferWidth; - PRUint8 *pSrcLineStart = (PRUint8 *)aXImage->data; - if (bits_per_pixel == 16) { - for (y=0; ybytes_per_line; - } - return PR_TRUE; - } - else if (bits_per_pixel == 24) { - PRUint8 *src = (PRUint8*)aXImage->data; - for (y=0; ybytes_per_line; - } - return PR_TRUE; - } - else if (bits_per_pixel == 32) { - for (y=0; ybytes_per_line; - } - return PR_TRUE; - } - else { - NS_ASSERTION(0, "do not support current bits_per_pixel"); - return PR_FALSE; - } -} - -PRBool -nsAntiAliasedGlyph::SetSize(GlyphMetrics *aGlyphMetrics) -{ - mAscent = aGlyphMetrics->ascent; - mDescent = aGlyphMetrics->descent; - mLBearing = aGlyphMetrics->lbearing; - mRBearing = aGlyphMetrics->rbearing; - mWidth = aGlyphMetrics->width; - mHeight = aGlyphMetrics->height; - mAdvance = aGlyphMetrics->advance; - return PR_TRUE; -} diff --git a/gfx/src/x11shared/nsAntiAliasedGlyph.h b/gfx/src/x11shared/nsAntiAliasedGlyph.h deleted file mode 100644 index 65d84a641634..000000000000 --- a/gfx/src/x11shared/nsAntiAliasedGlyph.h +++ /dev/null @@ -1,85 +0,0 @@ - -#ifndef NSANTIALIASEDGLYPH_H -#define NSANTIALIASEDGLYPH_H - -#include "gfx-config.h" -#include "nscore.h" - -#ifdef MOZ_ENABLE_FREETYPE2 -#include -#include FT_GLYPH_H -#endif - -struct _XImage; - -#ifndef MIN -#define MIN(a,b) (((a) <= (b)) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a,b) (((a) >= (b)) ? (a) : (b)) -#endif - -#define GLYPH_LEFT_EDGE(m) MIN(0, (m)->lbearing) -#define GLYPH_RIGHT_EDGE(m) MAX((m)->width, (m)->rbearing) - -typedef struct _GlyphMetrics { - PRUint32 width; - PRUint32 height; - PRInt32 lbearing; - PRInt32 rbearing; - PRInt32 advance; - PRInt32 ascent; - PRInt32 descent; -} GlyphMetrics; - -// -// Grey scale image -// -class nsAntiAliasedGlyph { -public: - nsAntiAliasedGlyph(PRUint32 aWidth, PRUint32 aHeight, PRUint32 aBorder); - ~nsAntiAliasedGlyph(); - - PRBool Init(); // alloc a buffer - PRBool Init(PRUint8 *aBuffer, PRUint32 aBufferLen); // use this buffer -#ifdef MOZ_ENABLE_FREETYPE2 - PRBool WrapFreeType(FT_BBox *aBbox, FT_BitmapGlyph aSlot, - PRUint8 *aBuffer, PRUint32 aBufLen); -#endif - - inline PRUint32 GetBorder() { return mBorder; }; - inline PRUint8 *GetBuffer() { return mBuffer; }; - inline PRUint32 GetBufferLen() { return mBufferLen; }; - inline PRUint32 GetBufferWidth() { return mBufferWidth; }; - inline PRUint32 GetBufferHeight() { return mBufferHeight; }; - - inline PRInt32 GetAdvance() { return mAdvance; }; - inline PRInt32 GetLBearing() { return mLBearing; }; - inline PRInt32 GetRBearing() { return mRBearing; }; - inline PRUint32 GetWidth() { return mWidth; }; - inline PRUint32 GetHeight() { return mHeight; }; - - PRBool SetImage(XCharStruct *, _XImage *); - PRBool SetSize(GlyphMetrics *); - -protected: - PRUint32 mBorder; - PRInt32 mAscent; - PRInt32 mDescent; - PRInt32 mLBearing; - PRInt32 mRBearing; - PRInt32 mAdvance; - PRUint32 mWidth; - PRUint32 mHeight; - PRUint32 mMaxWidth; - PRUint32 mMaxHeight; - PRUint32 mBufferWidth; // mWidth may be smaller - PRUint32 mBufferHeight; // mHeight may be smaller - PRBool mOwnBuffer; - PRUint8 *mBuffer; - PRUint32 mBufferLen; -}; - - - -#endif /* NSANTIALIASEDGLYPH_H */ diff --git a/gfx/src/x11shared/nsFT2FontCatalog.cpp b/gfx/src/x11shared/nsFT2FontCatalog.cpp deleted file mode 100644 index 164a6ed95984..000000000000 --- a/gfx/src/x11shared/nsFT2FontCatalog.cpp +++ /dev/null @@ -1,2477 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "gfx-config.h" -#include "nsFT2FontCatalog.h" -#include "nsFontDebug.h" - -PRUint32 gFontDebug = 0 | NS_FONT_DEBUG_FONT_SCAN; - -#if (defined(MOZ_ENABLE_FREETYPE2)) - -#include -#include -#include -#include -#include -#include -#include -#include "nsAppDirectoryServiceDefs.h" -#include "nsLocalFile.h" -#include "nsIEnumerator.h" -#include "nsITimelineService.h" -#include "nsIMutableArray.h" - -// -// Short overview: -// This code is here primarily to solve this problem: getting the list -// of valid glyphs in a TrueType font is very expensive when using -// the FreeType2 library. To solve this problem this code looks for -// a pre-built summary file in the font dir. If this font summary -// file is missing it is built and stored in the font dir if possible -// so it need not be generated by every user. If the user cannot write -// in the font dir the summary is stored in a per-user dir -// (ie: $HOME/.mozilla/fontsummaries). -// -// The routines are in alphabetic order to assist people reading -// this code printed on paper in finding the routines. -// -// The interesting high level entry points are: -// -// nsFT2FontCatalog::InitGlobals(); -// Called during startup to read (and update) the font catalog(s). -// -// nsFT2FontCatalog::GetFontNames(); -// Called when the font code is looking for a font. -// -// Some interesting low level entry points are: -// -// nsFT2FontCatalog::NewFceFromFontFile(); -// Called to get a TrueType font summary. -// Uses FreeType2 to actually open the font file. -// This checks for invalid glyphs so this can take a while. -// The summary will later be stored in the disk font catalog. -// -// nsFT2FontCatalog::NewFceFromSummary(); -// Called to get the TrueType font summary from the disk font catalog. -// - -// Solaris is missing a prototype for ctime -extern "C" {char *ctime(const time_t *timep);} - -#include -#include FT_GLYPH_H -#include FT_FREETYPE_H -#include FT_TRUETYPE_TABLES_H -#include FT_TRUETYPE_IDS_H - -// these should be static but the compilier complains -extern nsFontVendorName sVendorNamesList[]; -extern nsulCodePageRangeLanguage ulCodePageRange1Language[]; -extern nsulCodePageRangeLanguage ulCodePageRange2Language[]; - -nsHashtable* nsFT2FontCatalog::sVendorNames = nsnull; -nsIPref* nsFT2FontCatalog::sPref = nsnull; - -#endif - -// -// Implementation of Interfaces nsIFontCatalogService -// -NS_IMPL_ISUPPORTS1(nsFT2FontCatalog, nsIFontCatalogService) - -nsFT2FontCatalog::nsFT2FontCatalog() -#ifdef MOZ_ENABLE_FREETYPE2 - : mFontCatalog(nsnull), - mRange1Language(nsnull), - mRange2Language(nsnull) -#endif -{ -#if (defined(MOZ_ENABLE_FREETYPE2)) - nsresult rv; - mAvailableFontCatalogService = PR_FALSE; - - mFt2 = do_GetService(NS_FREETYPE2_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - // FreeType is not available - return; - } - - FT_Library lib; - mFt2->GetLibrary(&lib); - if (!lib) { - // FreeType is not available - return; - } - - if (!InitGlobals(lib)) { - // Font Catalog Service is not available - return; - } - mAvailableFontCatalogService = PR_TRUE; -#endif -} - -nsFT2FontCatalog::~nsFT2FontCatalog() -{ -#if (defined(MOZ_ENABLE_FREETYPE2)) - FreeGlobals(); -#endif -} - -NS_IMETHODIMP -nsFT2FontCatalog::GetFontCatalogEntries(const nsACString & aFamilyName, - const nsACString & aLanguage, - PRUint16 aWeight, - PRUint16 aWidth, - PRUint16 aSlant, - PRUint16 aSpacing, - nsIArray **_retval) -{ -#if (!defined(MOZ_ENABLE_FREETYPE2)) - *_retval = nsnull; - return NS_OK; -#else - if (mAvailableFontCatalogService == PR_FALSE) { - *_retval = nsnull; - return NS_OK; - } - - nsFontCatalog *fc = NewFontCatalog(); - if (!fc) - return NS_ERROR_OUT_OF_MEMORY; - - GetFontNames(aFamilyName, aLanguage, aWeight, aWidth, aSlant, aSpacing, fc); - nsCOMPtr aFce; - nsCOMPtr genericFce; - nsCOMPtr entries = - do_CreateInstance(NS_ARRAY_CONTRACTID); - NS_ENSURE_STATE(entries); - - int i; - for (i = 0; i < fc->numFonts; i++) { - aFce = nsFreeTypeGetFaceID(fc->fonts[i]); - genericFce = do_QueryInterface(aFce); - entries->InsertElementAt(genericFce, 0, PR_FALSE); - } - - free(fc->fonts); - free(fc); - *_retval = entries; - NS_ADDREF(*_retval); -#endif - return NS_OK; -} - -//-------------------------------------------------- - -#if (defined(MOZ_ENABLE_FREETYPE2)) - -void -nsFT2FontCatalog::AddDir(nsDirCatalog *dc, nsDirCatalogEntry *dir) -{ - if (dc->numDirs >= dc->numSlots) { - dc->numSlots += PR_MAX(1, PR_MIN(dc->numDirs, 128)); - dc->dirs = (nsDirCatalogEntry **)realloc(dc->dirs, - dc->numSlots*sizeof(nsDirCatalogEntry *)); - } - dc->dirs[dc->numDirs] = dir; - dc->numDirs++; -} - -PRBool -nsFT2FontCatalog::AddFceIfCurrent(const char *aFileName, - nsHashtable* aFceHash, - PRInt64 aFileModTime, - nsFontCatalog *aFontCatalog) -{ - int i; - nsCStringKey key(aFileName); - - // - // get it from the font summaries - // - nsFontCatalogEntry *fce = (nsFontCatalogEntry *)aFceHash->Get(&key); - if (!fce) - return PR_FALSE; - - // - // Check the time - // - PRInt64 fs_modtime = fce->mMTime; - LL_DIV(aFileModTime, aFileModTime, 1000); // microsec -> millisec - if (LL_NE(aFileModTime, fs_modtime)) - return PR_FALSE; - - // - // Move to the font catalog - // - aFceHash->Remove(&key); - AddFont(aFontCatalog, fce); - - // - // get other faces of the font - // - for (i=1; imNumFaces; i++) { - nsCAutoString key_str(aFileName); - // We use this hash when we are checking the files' timestamp. - // Since we do not want to open the file we cannot use the - // ttc face names (we would need to open the font to get that). - // So for the key we append a slash and number to give us a unique key - // for each ttc face. - char buf[20]; - sprintf(buf, "/%d", i); - key_str.Append(buf); - key = key_str; - fce = (nsFontCatalogEntry *)aFceHash->Get(&key); - NS_ASSERTION(fce, "additional font faces missing"); - if (!fce) { - FONT_CATALOG_PRINTF(("missing font face %d, %s", i, aFileName)); - return PR_FALSE; - } - aFceHash->Remove(&key); - AddFont(aFontCatalog, fce); - } - - return PR_TRUE; -} - -void -nsFT2FontCatalog::AddFont(nsFontCatalog *fc, nsFontCatalogEntry *fce) -{ - if (fc->numFonts >= fc->numSlots) { - fc->numSlots += PR_MAX(1, PR_MIN(fc->numFonts, 128)); - fc->fonts = (nsFontCatalogEntry **)realloc(fc->fonts, - fc->numSlots*sizeof(nsFontCatalogEntry *)); - } - fc->fonts[fc->numFonts] = fce; - fc->numFonts++; -} - -int -nsFT2FontCatalog::CheckFontSummaryVersion(nsNameValuePairDB *aDB) -{ - const char *type, *name, *value; - unsigned int num, major, minor, rev; - int result = FC_FILE_GARBLED; - - if (aDB->GetNextGroup(&type, FONT_SUMMARY_VERSION_TAG)) { - while (aDB->GetNextElement(&name, &value) > 0) { - if (*name == '\0') // ignore comments - continue; - if (strcmp(name, "Version")==0) { - num = sscanf(value, "%u.%u.%u", &major, &minor, &rev); - if (num != 3) { - FONT_CATALOG_PRINTF(("failed to parse version number (%s)", value)); - return result; - } - // FONT_SUMMARY_VERSION_MAJOR - // It is presumed that major versions are not backwards compatibile. - if (major == FONT_SUMMARY_VERSION_MAJOR) - result = FC_FILE_OKAY; - else - FONT_CATALOG_PRINTF(("version major %d != %d", major, - FONT_SUMMARY_VERSION_MAJOR)); - - // FONT_SUMMARY_VERSION_MINOR - // If there is a backwards compatibility with different - // minor versions put the test here. - - // FONT_SUMMARY_VERSION_REV - // if there should not be backwards compatibility issues - // with different revisions. - } - } - } - - return result; -} - -#ifdef DEBUG -void -nsFT2FontCatalog::DumpFontCatalog(nsFontCatalog *fc) -{ - int i; - for (i=0; inumFonts; i++) { - nsFontCatalogEntry *fce; - fce = fc->fonts[i]; - if (!fce->mFlags&FCE_FLAGS_ISVALID) - continue; - DumpFontCatalogEntry(fce); - } -} -#endif - -#ifdef DEBUG -void -nsFT2FontCatalog::DumpFontCatalogEntry(nsFontCatalogEntry *fce) -{ - printf(" fce->mFontFileName = %s\n", fce->mFontFileName); - printf(" fce->mMTime = %ld %s", fce->mMTime,ctime(&fce->mMTime)); - printf(" fce->mFlags = 0x%08x\n", fce->mFlags); - printf(" fce->mFaceIndex = %d\n", fce->mFaceIndex); - printf(" fce->mNumFaces = %d\n", fce->mNumFaces); - printf(" fce->mFontType = %s\n", fce->mFontType); - printf(" fce->mFamilyName = %s\n", fce->mFamilyName); - printf(" fce->mStyleName = %s\n", fce->mStyleName); - printf(" fce->mNumGlyphs = %d\n", fce->mNumGlyphs); - printf(" fce->mNumUsableGlyphs = %d\n", fce->mNumUsableGlyphs); - printf(" fce->mFaceFlags = 0x%08lx\n", fce->mFaceFlags); - printf(" fce->mStyleFlags = 0x%08lx\n", fce->mStyleFlags); - printf(" style: "); - printf("%s, ", fce->mStyleFlags & FT_STYLE_FLAG_ITALIC ? - "italic" : "roman"); - printf("%s", fce->mStyleFlags & FT_STYLE_FLAG_BOLD ? - "bold" : "regular"); - printf("\n"); - printf(" fce->mWeight = %d\n", fce->mWeight); - printf(" fce->mWidth = %d\n", fce->mWidth); - printf(" lang groups (0x%08lx, 0x%08lx): ", - fce->mCodePageRange1, fce->mCodePageRange2); - - if ((fce->mCodePageRange1 == 0) - && (fce->mCodePageRange2 == 0)) { - printf("guessing latin1 (%d glyphs)", fce->mNumGlyphs); - if (fce->mNumGlyphs > 300) { - printf("why no lang groups for %s (%s) and so many (%d) glyphs \n", - fce->mFamilyName, fce->mFontFileName, fce->mNumGlyphs); - } - } - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_LATIN1) - || (fce->mCodePageRange1 & TT_OS2_CPR1_MAC_ROMAN) - || (fce->mCodePageRange2 & TT_OS2_CPR2_WE_LATIN1) - || (fce->mCodePageRange2 & TT_OS2_CPR2_US)) - printf("latin1 (iso8859-1), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_LATIN2) - || (fce->mCodePageRange2 & TT_OS2_CPR2_LATIN2)) - printf("latin2 (iso8859-2), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_CYRILLIC) - || (fce->mCodePageRange2 & TT_OS2_CPR2_CYRILLIC)) - printf("cyrillic (iso8859-5), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_GREEK) - || (fce->mCodePageRange2 & TT_OS2_CPR2_GREEK) - || (fce->mCodePageRange2 & TT_OS2_CPR2_GREEK_437G)) - printf("greek (iso8859-7), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_TURKISH) - || (fce->mCodePageRange2 & TT_OS2_CPR2_TURKISH)) - printf("turkish (iso8859-9), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_HEBREW) - || (fce->mCodePageRange2 & TT_OS2_CPR2_HEBREW)) - printf("hebrew (iso8859-8), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_ARABIC) - || (fce->mCodePageRange2 & TT_OS2_CPR2_ARABIC) - || (fce->mCodePageRange2 & TT_OS2_CPR2_ARABIC_708)) - printf("arabic (iso8859-6), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_BALTIC) - || (fce->mCodePageRange2 & TT_OS2_CPR2_BALTIC)) - printf("baltic (iso8859-4), "); - - if (fce->mCodePageRange1 & TT_OS2_CPR1_VIETNAMESE) - printf("vietnamese (viscii1.1-1), "); - - if (fce->mCodePageRange1 & TT_OS2_CPR1_THAI) - printf("thai (tis620.2533-1), "); - - if (fce->mCodePageRange1 & TT_OS2_CPR1_JAPANESE) - printf("japanese (jisx0208.1990-0), "); - - if (fce->mCodePageRange1 & TT_OS2_CPR1_CHINESE_SIMP) - printf("simplified Chinese (gb2312.1980-1), "); - - if ((fce->mCodePageRange1 & TT_OS2_CPR1_KO_WANSUNG) - || (fce->mCodePageRange1 & TT_OS2_CPR1_KO_JOHAB)) - printf("korean (ksc5601.1992-3), "); - - if (fce->mCodePageRange1 & TT_OS2_CPR1_CHINESE_TRAD) - printf("traditional Chinese (big5-0), "); - - if (fce->mCodePageRange1 & TT_OS2_CPR1_SYMBOL) - printf("symbol (misc-fontspecific), "); - - if (fce->mCodePageRange2 & TT_OS2_CPR2_RUSSIAN) - printf("russian (koi8-r), "); - - if (fce->mCodePageRange2 & TT_OS2_CPR2_NORDIC) - printf("nordic (iso8859-10), "); - - if (fce->mCodePageRange2 & TT_OS2_CPR2_CA_FRENCH) - printf("canadian french (iso8859-1), "); - - if (fce->mCodePageRange2 & TT_OS2_CPR2_ICELANDIC) - printf("icelandic (iso8859-1), "); - - if (fce->mCodePageRange2 & TT_OS2_CPR2_PORTUGESE) - printf("portugese (iso8859-1), "); - - printf("\n"); - - printf(" fce->mVendorID = %4s\n", fce->mVendorID); - printf(" fce->mFoundryName = %s\n", fce->mFoundryName); - printf(" fce->mEmbeddedBitmapHeights="); - for (int i=0; imNumEmbeddedBitmaps; i++) - printf("%d,", fce->mEmbeddedBitmapHeights[i]); - printf("\n"); - printCCMap(fce->mCCMap); -} -#endif - -void -nsFT2FontCatalog::FixUpFontCatalog(nsFontCatalog *fc) -{ - int i; - for (i=0; inumFonts; i++) { - nsFontCatalogEntry *fce; - fce = fc->fonts[i]; - if (!fce->mFlags&FCE_FLAGS_ISVALID) - continue; - // some TrueType fonts seem to have weights in the 1 to 9 range - if ((fce->mWeight>=1) && (fce->mWeight<=9)) { - if (mIsNewCatalog) - FONT_CATALOG_PRINTF(("change weight from %d to %d, %s", - fce->mWeight, fce->mWeight*100, fce->mFamilyName)); - fce->mWeight *= 100; - } - if ((fce->mWeight<100) || (fce->mWeight>900)) { - FONT_CATALOG_PRINTF(("invalid weight %d, %s", fce->mWeight, - fce->mFamilyName)); - fce->mFlags &= ~FCE_FLAGS_ISVALID; - continue; - } - if (fce->mWidth>8) { - FONT_CATALOG_PRINTF(("limit width from %d to 8, %s", fce->mWidth, - fce->mFamilyName)); - fce->mWidth = 8; - } - nsCAutoString familyName(fce->mFamilyName); - free((void*)fce->mFamilyName); - ToLowerCase(familyName); - // nsFontMetricsGTK (like XLFD) does not allow a dash in the name - familyName.ReplaceChar('-', ' '); - fce->mFamilyName = strdup(familyName.get()); - if (!fce->mFamilyName) { - fce->mFlags &= ~FCE_FLAGS_ISVALID; - continue; - } - - nsCAutoString vendorID(fce->mVendorID); - ToLowerCase(vendorID); - vendorID.StripChars(" "); - nsCStringKey key(vendorID); - const char *vendorStr = (const char *)sVendorNames->Get(&key); - if (!vendorStr) { - if (fce->mVendorID[0]) - vendorStr = fce->mVendorID; - else - vendorStr = ""; - } - nsCAutoString vendorName(vendorStr); - ToLowerCase(vendorName); - fce->mFoundryName = strdup(vendorName.get()); - if (!fce->mFoundryName) { - fce->mFlags &= ~FCE_FLAGS_ISVALID; - continue; - } - if ((fce->mCodePageRange1==0) && (fce->mCodePageRange2==0) - && !(fce->mFlags&FCE_FLAGS_SYMBOL)) { - // no lang group set so try guessing Latin1 - NS_ASSERTION(fce->mNumGlyphs<=300, - "font has no lang group bits set AND has over 300 glyphs"); - if (fce->mNumGlyphs>300) - FONT_CATALOG_PRINTF(("no CodePageRange bits but %d glyphs, %s", - fce->mNumGlyphs, fce->mFamilyName)); - fce->mCodePageRange1 |= TT_OS2_CPR1_LATIN1; - } - } -} - -PRBool -nsFT2FontCatalog::FreeFceHashEntry(nsHashKey* aKey, void* aData, void* aClosure) -{ - nsFontCatalogEntry *fce = (nsFontCatalogEntry *)aData; - FreeFontCatalogEntry(fce); - return PR_TRUE; -} - -void -nsFT2FontCatalog::FreeFontCatalog(nsFontCatalog *fc) -{ - int i; - for (i=0; inumFonts; i++) { - nsFontCatalogEntry *fce; - fce = fc->fonts[i]; - FreeFontCatalogEntry(fce); - } - free(fc->fonts); - free(fc); -} - -void -nsFT2FontCatalog::FreeDirCatalog(nsDirCatalog *dc) -{ - int i; - for (i=0; inumDirs; i++) { - nsDirCatalogEntry *dce; - dce = dc->dirs[i]; - FreeDirCatalogEntry(dce); - } - free(dc->dirs); - free(dc); -} - -void -nsFT2FontCatalog::FreeDirCatalogEntry(nsDirCatalogEntry *dce) -{ - if (!dce) { - NS_ASSERTION(dce, "dce is null"); - return; - } - - FREE_IF(dce->mDirName); - free(dce); -} - - -void -nsFT2FontCatalog::FreeFontCatalogEntry(nsFontCatalogEntry *fce) -{ - if (!fce) { - NS_ASSERTION(fce, "fce is null"); - return; - } - - FREE_IF(fce->mFontFileName); - FREE_IF(fce->mFontType); - FREE_IF(fce->mFamilyName); - FREE_IF(fce->mStyleName); - FREE_IF(fce->mFoundryName); - FREE_IF(fce->mEmbeddedBitmapHeights); - if (fce->mCCMap) - FreeCCMap(fce->mCCMap); - free(fce); -} - -void -nsFT2FontCatalog::FreeGlobals() -{ - if (mFontCatalog) { - FreeFontCatalog(mFontCatalog); - mFontCatalog = nsnull; - } - - // sVendorNames elements are not alloc'd so no need call Reset - delete sVendorNames; - - delete mRange1Language; - delete mRange2Language; - - NS_IF_RELEASE(sPref); -} - -void -nsFT2FontCatalog::GetDirsPrefEnumCallback(const char* aName, void* aClosure) -{ - nsDirCatalog *dirCatalog = (nsDirCatalog *)aClosure; - nsDirCatalogEntry *dce; - dce = (nsDirCatalogEntry *)calloc(1, sizeof(nsDirCatalogEntry)); - if (!dce) - return; - // native charset?! - sPref->CopyCharPref(aName, (char **)&dce->mDirName); - if (!dce->mDirName) - return; - AddDir(dirCatalog, dce); -} - -PRInt32 * -nsFT2FontCatalog::GetEmbeddedBitmapHeights(nsFontCatalogEntry *aFce) -{ - return aFce->mEmbeddedBitmapHeights; -} - -PRInt32 -nsFT2FontCatalog::GetFaceIndex(nsFontCatalogEntry *aFce) -{ - return aFce->mFaceIndex; -} - -const char* -nsFT2FontCatalog::GetFamilyName(nsFontCatalogEntry *aFce) -{ - return aFce->mFamilyName; -} - -const char* -nsFT2FontCatalog::GetFileName(nsFontCatalogEntry *aFce) -{ - return aFce->mFontFileName; -} - -int -nsFT2FontCatalog::GetFontCatalog(FT_Library lib, nsFontCatalog *aFontCatalog, - nsDirCatalog *aOldDirCatalog) -{ - int i; - nsresult rv; - nsCAutoString font_summaries_dir_path; - nsCAutoString font_download_dir_path; - PRBool exists; - nsCOMPtr font_summaries_dir, font_download_dir; - - if (lib) { - // - // Get the dir for downloaded fonts - // - rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILES_ROOT_DIR, getter_AddRefs(font_download_dir)); - if (NS_FAILED(rv)) - goto cleanup_and_return; - - rv = font_download_dir->AppendNative(FONT_DOWNLOAD_SUBDIR); - if (NS_FAILED(rv)) - goto cleanup_and_return; - exists = PR_FALSE; - rv = font_download_dir->Exists(&exists); - if (NS_FAILED(rv)) - goto cleanup_and_return; - - if (!exists) { - rv = font_download_dir->Create(nsIFile::DIRECTORY_TYPE, 0775); - if (NS_FAILED(rv)) - goto cleanup_and_return; - } - rv = font_download_dir->GetNativePath(font_download_dir_path); - if (NS_FAILED(rv)) - goto cleanup_and_return; - - // - // Get the user dir for font catalogs - // - rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILES_ROOT_DIR, getter_AddRefs(font_summaries_dir)); - if (NS_FAILED(rv)) - goto cleanup_and_return; - - rv = font_summaries_dir->AppendNative(FONT_DOWNLOAD_SUBDIR); - if (NS_FAILED(rv)) - goto cleanup_and_return; - rv = font_summaries_dir->AppendNative(FONT_SUMMARIES_SUBDIR); - if (NS_FAILED(rv)) - goto cleanup_and_return; - exists = PR_FALSE; - rv = font_summaries_dir->Exists(&exists); - if (NS_FAILED(rv)) - goto cleanup_and_return; - - if (!exists) { - rv = font_summaries_dir->Create(nsIFile::DIRECTORY_TYPE, 0775); - if (NS_FAILED(rv)) - goto cleanup_and_return; - } - rv = font_summaries_dir->GetNativePath(font_summaries_dir_path); - if (NS_FAILED(rv)) - goto cleanup_and_return; - - // - // Get the font summaries for the public font dirs - // - for (i=0; inumDirs; i++) { - HandleFontDir(lib, aFontCatalog, font_summaries_dir_path, - nsDependentCString(aOldDirCatalog->dirs[i]->mDirName)); - } - - // - // Get the font summaries for the downloaded/private font dir - // - HandleFontDir(lib, aFontCatalog, font_summaries_dir_path, font_download_dir_path); - } - - return 0; - -cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontCatalog::GetFontCatalog failed")); - return -1; -} - -void -nsFT2FontCatalog::GetFontNames(const nsACString & aFamilyName, - const nsACString & aLanguage, - PRUint16 aWeight, - PRUint16 aWidth, - PRUint16 aSlant, - PRUint16 aSpacing, - nsFontCatalog* aFC) -{ - int i; - PRUint16 min_weight = PR_MAX(0, aWeight-125); - PRUint16 max_weight = PR_MIN(999, aWeight+125); - nsCAutoString familyName, language; - FONT_CATALOG_PRINTF(("looking for FreeType font matching")); - - ToLowerCase(aFamilyName, familyName); - ToLowerCase(aLanguage, language); - - FONT_CATALOG_PRINTF(("familyName=%s; language=%s; " - "weight=%d; width=%d; slant=%d; spacing=%d", - familyName.get(), language.get(), - aWeight, aWidth, aSlant, aSpacing)); - - unsigned long bit1 = GetRangeLanguage(language, CPR1); - unsigned long bit2 = GetRangeLanguage(language, CPR2); - - PRUint16 italicBit = 0; - switch (aSlant) { - case kFCSlantRoman: - break; - case kFCSlantItalic: - case kFCSlantOblique: - case kFCSlantReverseItalic: - case kFCSlantReverseOblique: - italicBit = 1; - break; - default: - break; - } - - PRUint16 monoBit = 0; - switch (aSpacing) { - case kFCSpacingMonospace: - monoBit = 0; - break; - case kFCSpacingProportional: - monoBit = 1; - break; - default: - break; - } - - /* column headers for the debug output*/ - FONT_CATALOG_PRINTF(("%s\t%-20s\t%-8s\t%-8s\t%-8s%-8s%-8s\t%-8s\t", - "mFlags", - "mFamilyName", - "mCodePageRange1", - "mCodePageRange2", - "mWeight", - "mWidth", - "mStyleFlags", - "fce->mFaceFlags")); - - for (i=0; inumFonts; i++) { - nsFontCatalogEntry *fce = mFontCatalog->fonts[i]; - // not all "fce" are valid - if (!fce->mFlags&FCE_FLAGS_ISVALID) - continue; - // family - if (!familyName.IsEmpty() && !familyName.Equals(fce->mFamilyName)) - continue; - // language - if (!language.IsEmpty() && - !((fce->mCodePageRange1 & bit1) || (fce->mCodePageRange2 & bit2))) - continue; - // weight (the meaning is not well defined so allow some variance) - if ((aWeight != kFCWeightAny) - && ((fce->mWeight < min_weight) || (fce->mWeight > max_weight))) - continue; - // width - if ((aWidth != kFCWidthAny) && (aWidth != fce->mWidth)) - continue; - // slant - if ((aSlant != kFCSlantAny) - && !((fce->mStyleFlags & FT_STYLE_FLAG_ITALIC) == italicBit)) - continue; - // spacing - if ((aSpacing != kFCSpacingAny) - && !((fce->mFaceFlags & FT_FACE_FLAG_FIXED_WIDTH) == monoBit)) - continue; - // match all patterns - FONT_CATALOG_PRINTF(("%0x\t%-20s\t%08lx\t%08lx\t%i\t%i\t%08lx\t%08lx", - fce->mFlags, - fce->mFamilyName, - fce->mCodePageRange1, - fce->mCodePageRange2, - fce->mWeight, - fce->mWidth, - fce->mStyleFlags, - fce->mFaceFlags)); - AddFont(aFC, fce); - } - return; -} - -PRBool -nsFT2FontCatalog::GetFontSummaryName(const nsACString &aFontDirName, // native charset - const nsACString &aFontSummariesDir, // native charset - nsACString &aFontSummaryFileName, - nsACString - &aFallbackFontSummaryFileName) -{ - int error; - struct stat file_info; - PRBool exists = PR_FALSE; - PRBool public_dir_writable = PR_FALSE; - PRBool public_summary_writable = PR_FALSE; - nsresult rv; - nsCOMPtr font_dir; - - // - // see if we should use the "public" one in the font dir itself - // or the "private" one in our $HOME/.mozilla/fontsummaries dir - // - font_dir = new nsLocalFile(); - font_dir->InitWithNativePath(aFontDirName); - rv = font_dir->IsWritable(&public_dir_writable); - if (NS_SUCCEEDED(rv) && public_dir_writable) { - FONT_CATALOG_PRINTF(("can write \"%s\"", PromiseFlatCString(aFontDirName).get())); - nsCOMPtr summary_file = new nsLocalFile(); - summary_file->InitWithNativePath(aFontDirName); - summary_file->AppendNative(PUBLIC_FONT_SUMMARY_NAME); - nsCAutoString font_summary_path; - summary_file->GetNativePath(font_summary_path); - FONT_CATALOG_PRINTF(("font_summary_path = \"%s\"", font_summary_path.get())); - rv = summary_file->Exists(&exists); - if (NS_SUCCEEDED(rv)) { - if (!exists) { - public_summary_writable = PR_TRUE; - aFontSummaryFileName = font_summary_path; - } - else { - FONT_CATALOG_PRINTF(("font summary \"%s\" exists", font_summary_path.get())); - rv = summary_file->IsWritable(&public_summary_writable); - if (NS_SUCCEEDED(rv) && public_summary_writable) { - FONT_CATALOG_PRINTF(("font summary \"%s\" is writable", - font_summary_path.get())); - public_summary_writable = PR_TRUE; - aFontSummaryFileName = font_summary_path; - } - } - } - } - - if (!public_summary_writable) { - // - // Generate the private font summary name from: - // 1) the user's product directory - // 2) the font dir's parent dir's device/inode - // 3) the font dir's name in that dir - // file name = - // .d.ndb - // eg: for: - // user's product dir "/home/bstell/.mozilla/fontsummaries" - // the font dir "/home/bstell/tt_font" - // where /home/bstell is inode 1234 on device 3,2 - // the name would be: - // - // /home/bstell/.mozilla/fontsummaries/tt_font.d0302.i1234.ndb - // - - // - // Split the parent dir and file name - // - PRInt32 slash = 0, last_slash = -1; - // RFindChar not coded so do it by hand - while ((slash=aFontDirName.FindChar('/', slash))>=0) { - last_slash = slash; - slash++; - } - if (last_slash < 0) { - FONT_CATALOG_PRINTF(("did not find a \"/\" in %s", - PromiseFlatCString(aFontDirName).get())); - return PR_FALSE; - } - int right_len = aFontDirName.Length() - last_slash - 1; - nsCAutoString parent_dir(Substring(aFontDirName, 0, last_slash)); - nsCAutoString font_dir_name_tail(Substring(aFontDirName, - last_slash+1, right_len)); - // - // Get the parent dir's device and inode - // - error = stat(PromiseFlatCString(parent_dir).get(), &file_info); - if (error) { - FONT_CATALOG_PRINTF(("failed to stat %s", - PromiseFlatCString(parent_dir).get())); - return PR_FALSE; - } - - int dev = file_info.st_dev; - int inode = file_info.st_ino; - FONT_CATALOG_PRINTF(("parent dir dev = %04x, inode = %d", dev, inode)); - char buf[64]; - sprintf(buf, ".d%04x.i%d", dev, inode); - font_dir_name_tail.Append(buf); - - // - // Build the font summary name - // - aFontSummaryFileName = aFontSummariesDir; - aFontSummaryFileName.Append("/"); - aFontSummaryFileName.Append(font_dir_name_tail); - aFontSummaryFileName.Append(FONT_SUMMARIES_EXTENSION); - - // - // Build the backup Font Summary name - // - aFallbackFontSummaryFileName = aFontDirName; - aFallbackFontSummaryFileName.Append("/"); - aFallbackFontSummaryFileName.Append(PUBLIC_FONT_SUMMARY_NAME); - } - - return PR_TRUE; -} - -const char * -nsFT2FontCatalog::GetFoundry(nsFontCatalogEntry *aFce) -{ - nsCAutoString foundry(aFce->mVendorID); - ToLowerCase(foundry); - foundry.StripChars(" "); - nsCStringKey key(foundry); - const char *vendorName = (const char *)sVendorNames->Get(&key); - if (!vendorName) { - if (aFce->mVendorID[0]) - vendorName = aFce->mVendorID; - else - vendorName = ""; - } - return vendorName; -} - -PRInt32 -nsFT2FontCatalog::GetNumEmbeddedBitmaps(nsFontCatalogEntry *aFce) -{ - return aFce->mNumEmbeddedBitmaps; -} - -PRBool -nsFT2FontCatalog::HandleFontDir(FT_Library aFreeTypeLibrary, - nsFontCatalog *aFontCatalog, - const nsACString &aFontSummariesDir, // native charset - const nsACString &aFontDirName) // native charset -{ - int i, status = -1; - PRBool rslt, current; - nsCAutoString fileName; - nsHashtable* fontFileNamesHash = nsnull; - nsHashtable* fallbackFceHash = nsnull; - nsresult rv; - nsCAutoString fontSummaryFilename, fallbackFontSummaryFilename; - nsFontCatalog *dirFontCatalog = nsnull; - PRBool moreFilesInDir = PR_FALSE; - nsCOMPtr dir; - nsCOMPtr dirLocal; - nsCOMPtr dirEntry; - nsCOMPtr dirIterator; - PRBool summary_needs_update = PR_FALSE; - nsFontCatalogEntry *fce; - - // - // temp holder for the font summaries in this dir - // - dirFontCatalog = NewFontCatalog(); - if (!dirFontCatalog) - goto cleanup_and_return; - // also hash to quick access - fontFileNamesHash = new nsHashtable(); - if (!fontFileNamesHash) - goto cleanup_and_return; - - // - // Figure out where the font summary is - // - rslt = GetFontSummaryName(aFontDirName, aFontSummariesDir, - fontSummaryFilename, - fallbackFontSummaryFilename); - if (!rslt) { - FONT_CATALOG_PRINTF(("failed to get font summary name for %s %s", - PromiseFlatCString(aFontDirName).get(), - PromiseFlatCString(aFontSummariesDir).get())); - goto cleanup_and_return; - } - - FONT_CATALOG_PRINTF(("for \"%s\":\n font summary = %s" - "\n fallback = %s", - PromiseFlatCString(aFontDirName).get(), - PromiseFlatCString(fontSummaryFilename).get(), - fallbackFontSummaryFilename.Length()>0 ? - fallbackFontSummaryFilename.get() - :"")); - - // - // Get the font summaries - // - ReadFontDirSummary(fontSummaryFilename, fontFileNamesHash); - - // - // Open the dir - // - dir = new nsLocalFile(); - dirLocal = do_QueryInterface(dir); - dirLocal->InitWithNativePath(aFontDirName); - rv = dir->GetDirectoryEntries(getter_AddRefs(dirIterator)); - if (NS_FAILED(rv)) { - FONT_CATALOG_PRINTF(("failed to open dir (get iterator) for %s", - PromiseFlatCString(aFontDirName).get())); - goto cleanup_and_return; - } - - rv = dirIterator->HasMoreElements(&moreFilesInDir); - if (NS_FAILED(rv)) { - FONT_CATALOG_PRINTF(("failed HasMoreElements")); - goto cleanup_and_return; - } - - // - // Compare the files in the dir to the font summaries - // - while (moreFilesInDir) { - PRBool isFile; - current = PR_FALSE; - rv = dirIterator->GetNext((nsISupports**)getter_AddRefs(dirEntry)); - if (NS_FAILED(rv)) { - FONT_CATALOG_PRINTF(("failed GetNext")); - goto cleanup_and_return; - } - //char *path; - dirEntry->GetNativePath(fileName); - FONT_CATALOG_PRINTF(("dirEntry = \"%s\"", fileName.get())); - rv = dirEntry->IsFile(&isFile); - if (NS_SUCCEEDED(rv) && isFile) { - PRInt64 modtime; - dirEntry->GetLastModifiedTime(&modtime); - current = AddFceIfCurrent(fileName.get(), fontFileNamesHash, - modtime, dirFontCatalog); - if (!current) { - // Ignore the font summary itself - if (fileName.Equals(fontSummaryFilename) || - fileName.Equals(fallbackFontSummaryFilename)) { - FONT_CATALOG_PRINTF(("font summary %s is not a font", fileName.get())); - current = PR_TRUE; - } - // If not in font summary, try the fallback summary - else if (fallbackFontSummaryFilename.Length()) { - if (!fallbackFceHash) { - fallbackFceHash = new nsHashtable(); - if (fallbackFceHash) { - ReadFontDirSummary(fallbackFontSummaryFilename, - fallbackFceHash); - } - } - if (fallbackFceHash) { - summary_needs_update = PR_TRUE; - current = AddFceIfCurrent(fileName.get(), fallbackFceHash, - modtime, dirFontCatalog); - } - } - - // - // If not found in font summary or fallback - // then scan the font - // - if (!current) { - summary_needs_update = PR_TRUE; - HandleFontFile(aFreeTypeLibrary, dirFontCatalog, - fileName.get()); - } - } - } - rv = dirIterator->HasMoreElements(&moreFilesInDir); - if (NS_FAILED(rv)) { - FONT_CATALOG_PRINTF(("failed HasMoreElements")); - goto cleanup_and_return; - } - } - - // - // if hash count != 0 then needs update - // - if (fontFileNamesHash->Count()) { - summary_needs_update = PR_TRUE; - } - - // - // Check if need to update font summary - // - if (summary_needs_update) { - FONT_CATALOG_PRINTF(("update the font summary")); - nsNameValuePairDB tmp_fc; - if (!tmp_fc.OpenTmpForWrite(fontSummaryFilename)) - return 0; // failed to write but still got font data - // print the Font Summary version - PrintFontSummaryVersion(&tmp_fc); - // print the font summaries - PrintFontSummaries(&tmp_fc, dirFontCatalog); - if (tmp_fc.HadError()) - return 0; // failed to write but still got font data - tmp_fc.RenameTmp(PromiseFlatCString(fontSummaryFilename).get()); - } - - // - // transfer the fce from this dir to the main font catalog - // - for (i=0; inumFonts; i++) { - fce = dirFontCatalog->fonts[i]; - AddFont(aFontCatalog, fce); - } - dirFontCatalog->numFonts = 0; - - status = 0; - -cleanup_and_return: - if(dirFontCatalog) - FreeFontCatalog(dirFontCatalog); - if(fontFileNamesHash) { - fontFileNamesHash->Reset(FreeFceHashEntry, nsnull); - delete fontFileNamesHash; - } - if(fallbackFceHash) { - fallbackFceHash->Reset(FreeFceHashEntry, nsnull); - delete fallbackFceHash; - } - return status; -} - -void -nsFT2FontCatalog::HandleFontFile(FT_Library aFreeTypeLibrary, - nsFontCatalog *aFontCatalog, - const char *aFontFileName) -{ - int j, num_faces; - nsFontCatalogEntry *fce; - - /* FONT_CATALOG_PRINTF(("handle font %s", aFontFileName)); */ - fce = NewFceFromFontFile(aFreeTypeLibrary, aFontFileName, - 0, &num_faces); - if (!fce) { - //FONT_CATALOG_PRINTF(("failed to catalog %s", aFontFileName)); - return; - } - AddFont(aFontCatalog, fce); - - /* loop thru the additional faces */ - for (j=1; jvendorID) { - nsCAutoString name(vn->vendorID); - ToLowerCase(name); - nsCStringKey key(name); - sVendorNames->Put(&key, (void*)vn->vendorName); - vn++; - } - - mRange1Language = new nsHashtable(); - if (!mRange1Language) - goto cleanup_and_return; - crl = ulCodePageRange1Language; - while (crl->language) { - nsCStringKey key(crl->language); - mRange1Language->Put(&key, &(crl->bit)); - crl++; - } - - mRange2Language = new nsHashtable(); - if (!mRange2Language) - goto cleanup_and_return; - crl = ulCodePageRange2Language; - while (crl->language) { - nsCStringKey key(crl->language); - mRange2Language->Put(&key, &(crl->bit)); - crl++; - } - - // get dirs list from prefs - dirCatalog = NewDirCatalog(); - if (!dirCatalog) - goto cleanup_and_return; - sPref->EnumerateChildren(prefix.get(), GetDirsPrefEnumCallback, - dirCatalog); - - NS_TIMELINE_START_TIMER("nsFT2FontCatalog::GetFontCatalog"); - GetFontCatalog(lib, mFontCatalog, dirCatalog); - NS_TIMELINE_STOP_TIMER("nsFT2FontCatalog::GetFontCatalog"); - NS_TIMELINE_MARK_TIMER("nsFT2FontCatalog::GetFontCatalog"); - FreeDirCatalog(dirCatalog); - - FixUpFontCatalog(mFontCatalog); -#ifdef DEBUG - if (dump_catalog) - DumpFontCatalog(mFontCatalog); -#endif - -#ifdef DEBUG - for (i=0; inumFonts; i++) { - if (mFontCatalog->fonts[i]->mFlags&FCE_FLAGS_ISVALID) - num_ftfonts++; - } - FONT_CATALOG_PRINTF(("can use %d TrueType fonts (font dirs hold %d files)", - num_ftfonts, mFontCatalog->numFonts)); -#endif - - return(PR_TRUE); - -cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontCatalog::InitGlobals failed")); - FreeGlobals(); - return(PR_FALSE); -} - -// -// Routine to tell if a char should be blank -// This routing is simplistic but Erik van der Poel recommended -// this and it seems to be sufficient for the windows code; -// In the windows code see SHOULD_BE_SPACE_CHAR(ch) -// -PRBool -nsFT2FontCatalog::IsSpace(FT_Long c) -{ - switch (c) { - case 0x0020: // ascii space - case 0x00A0: // non-breaking space - case 0x3000: // ideographic space - return PR_TRUE; - } - // 2000 == EN quad - // 2001 == EM quad - // 2002 == EN space - // 2003 == EM space - // 2004 == 3 per EM space - // 2005 == 4 per EM space - // 2006 == 6 per EM space - // 2007 == figure space - // 2008 == punction space - // 2009 == thin space - // 200A == hair space - // 200B == zero width space - - if ((c >= 0x2000) && (c <= 0x200b)) - return PR_TRUE; - return PR_FALSE; -} - -nsDirCatalog * -nsFT2FontCatalog::NewDirCatalog() -{ - nsDirCatalog *dc; - dc = (nsDirCatalog *)calloc(1, sizeof(nsDirCatalog)); - return dc; -} - -nsFontCatalogEntry * -nsFT2FontCatalog::NewFceFromFontFile(FT_Library aFreeTypeLibrary, - const char *aFontFileName, - int aFaceIndex, int * aNumFaces) -{ - PRUint32 i, len; - nsFontCatalogEntry *fce; - FT_Error fterror; - FT_Face face = nsnull; - FT_UInt glyph_index; - FT_GlyphSlot slot; - TT_OS2 *tt_os2; - int error; - struct stat file_info; - int num_checked = 0; - int blank_chars; - nsCompressedCharMap ccmapObj; - nsresult rv; - - fce = (nsFontCatalogEntry *)calloc(1, sizeof(nsFontCatalogEntry)); - if (!fce) - return nsnull; - - FONT_SCAN_PRINTF(("font %s ", aFontFileName)); - if (aFaceIndex) { - FONT_SCAN_PRINTF(("face %d ", aFaceIndex+1)); - } - - error = stat(aFontFileName, &file_info); - if (error) { - FONT_SCAN_PRINTF((" unable to stat font file")); - goto cleanup_and_return; - } - - fce->mFontFileName = strdup(aFontFileName); - if (!fce->mFontFileName) - goto no_memory_cleanup_and_return; - - fce->mMTime = file_info.st_mtime; - fce->mFaceIndex = aFaceIndex; - - // open the font - rv = mFt2->NewFace(aFreeTypeLibrary, aFontFileName, aFaceIndex, &face); - if (NS_FAILED(rv)) { - FONT_SCAN_PRINTF((" FreeType failed to open, error=%d", fterror)); - goto cleanup_and_return; - } - if (!FT_IS_SCALABLE(face)) { - FONT_SCAN_PRINTF((" not scalable, ignoring")); - goto cleanup_and_return; - } - - NS_ASSERTION(face->family_name,"font is missing FamilyName"); - if (!face->family_name) - goto cleanup_and_return; - nsTTFontFamilyEncoderInfo *ffei; - ffei = nsFreeType2::GetCustomEncoderInfo(face->family_name); - if (ffei) { - fce->mFlags = FCE_FLAGS_ISVALID | FCE_FLAGS_SYMBOL; - } - else { - for (i=0; i < face->num_charmaps; i++) { - - if (face->charmaps[i]->platform_id == TT_PLATFORM_MICROSOFT) { - if (face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS) { - fce->mFlags = FCE_FLAGS_ISVALID | FCE_FLAGS_UNICODE; - fterror = mFt2->SetCharmap(face, face->charmaps[i]); - if (fterror) { - FONT_SCAN_PRINTF(("failed to select unicode charmap")); - goto cleanup_and_return; - } - } -#if defined(TT_MS_ID_UCS_4) - else if (face->charmaps[i]->encoding_id == TT_MS_ID_UCS_4) { - fce->mFlags = FCE_FLAGS_ISVALID | FCE_FLAGS_UNICODE | FCE_FLAGS_SURROGATE; - fterror = mFt2->SetCharmap(face, face->charmaps[i]); - if (fterror) { - FONT_SCAN_PRINTF(("failed to select unicode charmap")); - goto cleanup_and_return; - } - break; - } -#endif - } - } - } - if (!fce->mFlags&FCE_FLAGS_ISVALID) { - FONT_SCAN_PRINTF(("%s is missing cmap", face->family_name)); - goto cleanup_and_return; - } - - mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); - if (!tt_os2) { - FONT_SCAN_PRINTF(("unable to get OS2 table")); - goto cleanup_and_return; - } - fce->mFontType = strdup("TrueType"); - if (!fce->mFontType) - goto no_memory_cleanup_and_return; - fce->mWeight = tt_os2->usWeightClass; - fce->mWidth = tt_os2->usWidthClass; - fce->mCodePageRange1 = tt_os2->ulCodePageRange1; - fce->mCodePageRange2 = tt_os2->ulCodePageRange2; - // sadly too many fonts have vendor ID blank - //NS_ASSERTION(*((char*)tt_os2->achVendID), "invalid vendor id"); - memset((char*)fce->mVendorID, 0, sizeof(fce->mVendorID)); - strncpy((char*)fce->mVendorID, (char*)tt_os2->achVendID, - sizeof(fce->mVendorID)-1); - fce->mNumFaces = face->num_faces; - if (aNumFaces!=nsnull) - *aNumFaces = face->num_faces; - - //FONT_CATALOG_PRINTF(("family = %s", face->family_name)); - fce->mFamilyName = strdup(face->family_name); - if (!fce->mFamilyName) - goto no_memory_cleanup_and_return; - - fce->mStyleName = strdup(face->style_name); - if (!fce->mStyleName) - goto no_memory_cleanup_and_return; - - fce->mFaceFlags = face->face_flags; - fce->mStyleFlags = face->style_flags; - fce->mNumGlyphs = face->num_glyphs; - - fce->mNumEmbeddedBitmaps = face->num_fixed_sizes; - if (fce->mNumEmbeddedBitmaps) { - fce->mEmbeddedBitmapHeights = (int*)calloc(fce->mNumEmbeddedBitmaps, - sizeof(fce->mEmbeddedBitmapHeights[0])); - if (!fce->mEmbeddedBitmapHeights) - goto no_memory_cleanup_and_return; - for (int i=0; imNumEmbeddedBitmaps; i++) - fce->mEmbeddedBitmapHeights[i] = face->available_sizes[i].height; - } - - if ((fce->mFlags & FCE_FLAGS_UNICODE) || (fce->mFlags & FCE_FLAGS_SURROGATE)) { - if (fce->mFlags & FCE_FLAGS_SURROGATE) { - ccmapObj.Extend(); - } - - // check fast methods are defined - PRBool has_fast_methods; - mFt2->SupportsExtFunc(&has_fast_methods); - - PRBool scan_done = PR_FALSE; - if (has_fast_methods) { - mFt2->GetFirstChar(face, &glyph_index, (FT_ULong*)&i); - if (glyph_index == 0) { - // no glyph in the font - scan_done = PR_TRUE; - } - } else { - i=0; - } - - len = NUM_UNICODE_CHARS; - if(fce->mFlags & FCE_FLAGS_SURROGATE) { - len = 0xFFFFF; - } - - blank_chars = 0; - slot = face->glyph; - FONT_SCAN_PRINTF((" ")); - - while (!scan_done && i < len) { - if (!has_fast_methods) { - mFt2->GetCharIndex(face, (FT_ULong)i, &glyph_index); - //FONT_CATALOG_PRINTF(("i=%d, glyph_index=%d", i, glyph_index)); - if (glyph_index == 0) { - goto next_char; - } - } - if (gFontDebug & NS_FONT_DEBUG_FONT_SCAN) { - if ((num_checked % 1000) == 0) { - FONT_SCAN_PRINTF(("\b\b\b\b\b\b\b\b\b\b\b\b\b\b%7d glyphs", num_checked)); - } - } - num_checked++; - rv = mFt2->LoadGlyph(face, glyph_index, - FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING); - //FONT_CATALOG_PRINTF(("fterror = %d", fterror)); - if (NS_FAILED(rv)) { - FONT_CATALOG_PRINTF(("error loading %d (glyph index = %d)", - i, glyph_index)); - goto next_char; - } - if (slot->format == ft_glyph_format_outline) { - //FONT_CATALOG_PRINTF(("n_contours=%d", slot->outline.n_contours)); - if ((slot->outline.n_contours==0) && (!IsSpace(i))) { - blank_chars++; - FT_Glyph glyph; - FT_BBox bbox; - mFt2->GetGlyph(slot, &glyph); - mFt2->GlyphGetCBox(glyph, ft_glyph_bbox_pixels, &bbox); - mFt2->DoneGlyph(glyph); - if((bbox.xMax==0) && (bbox.xMin==0) - && (bbox.yMax==0) && (bbox.yMin==0)) { - goto next_char; - } - FONT_SCAN_PRINTF(("no contours %d (glyph index = %d)\n", i, - glyph_index)); - FONT_CATALOG_PRINTF(("character 0x%04x no contour but glyph has " - "non-zero bounding box", i)); - NS_WARNING("character no contour but glyph has non-zero bounding box"); - } - } - else if (slot->format == ft_glyph_format_bitmap) { - // this "empty bitmap" test is just a guess - if ((slot->bitmap.rows==0) || (slot->bitmap.width==0)) { - FONT_CATALOG_PRINTF(("no bitmap for glyph 0x%04x", i)); - FONT_CATALOG_PRINTF(("continue at line %d", __LINE__)); - FONT_SCAN_PRINTF(("empty bitmap %d (glyph index = %d)\n", - i, glyph_index)); - goto next_char; - } - } - else { - NS_WARNING("need to test for empty (non-space char) glyph"); - } - ccmapObj.SetChar(i); - fce->mNumUsableGlyphs++; -next_char: - if (has_fast_methods) { - FT_ULong ncharcode; - mFt2->GetNextChar(face, (FT_ULong)i, &glyph_index, &ncharcode); - i = ncharcode; - if (glyph_index == 0) { - // no more glyph in the font - scan_done = PR_TRUE; - } - } else { - i++; - } - } - if (gFontDebug & NS_FONT_DEBUG_FONT_SCAN) { - FONT_SCAN_PRINTF(("\b\b\b\b\b\b\b\b\b\b\b\b\b\b%7d glyphs", num_checked)); - if (blank_chars) { - FONT_SCAN_PRINTF((" (%d invalid)", blank_chars)); - } - } - if (fce->mNumUsableGlyphs == 0) - fce->mFlags |= FCE_FLAGS_ISVALID; - - fce->mCCMap = ccmapObj.NewCCMap(); - } - else if (fce->mFlags & FCE_FLAGS_SYMBOL) { - FONT_SCAN_PRINTF(("uses custom encoder")); - if (ffei) { - nsCOMPtr mapper; - mapper = do_QueryInterface(ffei->mEncodingInfo->mConverter); - if (mapper) { - fce->mCCMap = MapperToCCMap(mapper); - } - } - } - else { - FONT_SCAN_PRINTF(("unknown font encoding")); - } - if (!fce->mCCMap) { - FONT_CATALOG_PRINTF(("Failed to copy CCMap")); - goto cleanup_and_return; - } - - mFt2->DoneFace(face); - - FONT_SCAN_PRINTF(("\n")); - return fce; - -// regardless of why we could not use the file we want to put it in the -// catalog so we do not reopen invalid files every time we startup -cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontCatalog::NewFceFromFontFile failed")); - fce->mFlags &= ~FCE_FLAGS_ISVALID; - fce->mFontType = strdup(""); - fce->mNumFaces = 0; - if (aNumFaces) - *aNumFaces = 0; - fce->mFamilyName = strdup(""); - fce->mFlags = 0; - fce->mStyleName = strdup(""); - FREE_IF(fce->mEmbeddedBitmapHeights); - if (face) - mFt2->DoneFace(face); - FONT_SCAN_PRINTF(("\n")); - return fce; - -no_memory_cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontCatalog::NewFceFromFontFile: out of memory")); - FREE_IF(fce->mFontFileName); - FREE_IF(fce->mFontType); - FREE_IF(fce->mFamilyName); - FREE_IF(fce->mStyleName); - if (fce->mCCMap) - FreeCCMap(fce->mCCMap); - FREE_IF(fce); - if (face) - mFt2->DoneFace(face); - FONT_SCAN_PRINTF(("\n")); - return nsnull; -} - -nsFontCatalogEntry * -nsFT2FontCatalog::NewFceFromSummary(nsNameValuePairDB *aDB) -{ - const char *type, *name, *value; - PRBool rslt; - nsFontCatalogEntry *fce = nsnull; - long longVal; - unsigned long uLongVal; - int num, intVal, i; - nsCompressedCharMap ccmapObj; - - fce = (nsFontCatalogEntry *)calloc(1, sizeof(nsFontCatalogEntry)); - if (!fce) - goto cleanup_and_return; - - if (!aDB->GetNextGroup(&type, "Font_", 5)) { - FONT_CATALOG_PRINTF(("file garbled: expected begin=Font_, got %s", type)); - goto cleanup_and_return; - } - - while (aDB->GetNextElement(&name, &value) > 0) { - if (STRMATCH(name,"FamilyName")) { - if (fce->mFamilyName) { - FONT_CATALOG_PRINTF(("family name defined multiple times (%s, %s)", - fce->mFamilyName, value)); - goto cleanup_and_return; - } - fce->mFamilyName = strdup(value); - if (!fce->mFamilyName) - goto cleanup_and_return; - } - else if (STRMATCH(name,"Flags")) { - if (fce->mFlags != 0) { - FONT_CATALOG_PRINTF(("Flags defined multiple times (%s)", - fce->mFontFileName?fce->mFontFileName:"")); - goto cleanup_and_return; - } - num = sscanf(value, "%lx", &uLongVal); - if (num != 1) { - FONT_CATALOG_PRINTF(("failed to parse Flags (%s)",value)); - goto cleanup_and_return; - } - fce->mFlags = uLongVal; - if (fce->mFlags & FCE_FLAGS_SURROGATE) { - ccmapObj.Extend(); - } - } - else if (STRMATCH(name,"FontFileName")) { - if (fce->mFontFileName) { - FONT_CATALOG_PRINTF(("font filename defined multiple times (%s, %s)", - fce->mFontFileName, value)); - goto cleanup_and_return; - } - fce->mFontFileName = strdup(value); - if (!fce->mFontFileName) - goto cleanup_and_return; - } - else if (STRMATCH(name,"MTime")) { - if (fce->mMTime != 0) { - FONT_CATALOG_PRINTF(("time defined multiple times (%s)", - fce->mFontFileName?fce->mFontFileName:"")); - goto cleanup_and_return; - } - num = sscanf(value, "%lu", &uLongVal); - if ((num != 1) || (uLongVal==0)) { - FONT_CATALOG_PRINTF(("failed to parse time (%s)",value)); - goto cleanup_and_return; - } - fce->mMTime = uLongVal; - } - else if (STRMATCH(name,"FontType")) { - if (fce->mFontType) { - FONT_CATALOG_PRINTF(("font type defined multiple times (%s, %s)", - fce->mFontType, value)); - goto cleanup_and_return; - } - fce->mFontType = strdup(value); - if (!fce->mFontType) - goto cleanup_and_return; - } - else if (STRMATCH(name,"FaceIndex")) { - if (fce->mFaceIndex != 0) { - FONT_CATALOG_PRINTF(("face index defined multiple times (%d, %s)", - fce->mFaceIndex, value)); - goto cleanup_and_return; - } - longVal = atol(value); - if (longVal<0) { - FONT_CATALOG_PRINTF(("failed to parse face index (%s)",value)); - goto cleanup_and_return; - } - fce->mFaceIndex = longVal; - } - else if (STRMATCH(name,"NumFaces")) { - if (fce->mNumFaces != 0) { - FONT_CATALOG_PRINTF(("num faces defined multiple times (%d, %s)", - fce->mNumFaces, value)); - goto cleanup_and_return; - } - intVal = atoi(value); - if (intVal<0) { - FONT_CATALOG_PRINTF(("failed to parse num faces (%s)",value)); - goto cleanup_and_return; - } - fce->mNumFaces = intVal; - } - else if (STRMATCH(name,"StyleName")) { - if (fce->mStyleName != 0) { - FONT_CATALOG_PRINTF(("font style defined multiple times (%s, %s)", - fce->mStyleName, value)); - goto cleanup_and_return; - } - fce->mStyleName = strdup(value); - if (!fce->mStyleName) - goto cleanup_and_return; - } - else if (STRMATCH(name,"NumGlyphs")) { - if (fce->mNumGlyphs != 0) { - FONT_CATALOG_PRINTF(("num glyphs defined multiple times (%d, %s)", - fce->mNumGlyphs, value)); - goto cleanup_and_return; - } - intVal = atoi(value); - if (intVal<0) { - FONT_CATALOG_PRINTF(("failed to parse num glyphs (%s)",value)); - goto cleanup_and_return; - } - fce->mNumGlyphs = intVal; - } - else if (STRMATCH(name,"NumUsableGlyphs")) { - if (fce->mNumUsableGlyphs != 0) { - FONT_CATALOG_PRINTF(("num usable glyphs defined multiple times (%d, %s)", - fce->mNumUsableGlyphs, value)); - goto cleanup_and_return; - } - intVal = atoi(value); - if (intVal<0) { - FONT_CATALOG_PRINTF(("failed to parse num usable glyphs (%s)",value)); - goto cleanup_and_return; - } - fce->mNumUsableGlyphs = intVal; - } - else if (STRMATCH(name,"FaceFlags")) { - if (fce->mFaceFlags != 0) { - FONT_CATALOG_PRINTF(("face flags defined multiple times (0x%lx, %s)", - fce->mFaceFlags, value)); - goto cleanup_and_return; - } - num = sscanf(value, "%lx", &uLongVal); - if (num != 1) { - FONT_CATALOG_PRINTF(("failed to parse face flags (%s)",value)); - goto cleanup_and_return; - } - fce->mFaceFlags = uLongVal; - } - else if (STRMATCH(name,"StyleFlags")) { - if (fce->mStyleFlags != 0) { - FONT_CATALOG_PRINTF(("style flags defined multiple times (0x%lx, %s)", - fce->mStyleFlags, value)); - goto cleanup_and_return; - } - num = sscanf(value, "%lx", &uLongVal); - if (num != 1) { - FONT_CATALOG_PRINTF(("failed to parse style flags (%s)",value)); - goto cleanup_and_return; - } - fce->mStyleFlags = uLongVal; - } - else if (STRMATCH(name,"Weight")) { - if (fce->mWeight != 0) { - FONT_CATALOG_PRINTF(("weight defined multiple times (0x%d, %s)", - fce->mWeight, value)); - goto cleanup_and_return; - } - intVal = atoi(value); - if ((intVal<0) || (intVal>950)) { - FONT_CATALOG_PRINTF(("failed to parse weight (%s)",value)); - goto cleanup_and_return; - } - fce->mWeight = (unsigned short)intVal; - } - else if (STRMATCH(name,"Width")) { - if (fce->mWidth != 0) { - FONT_CATALOG_PRINTF(("width defined multiple times (0x%d, %s)", - fce->mWeight, value)); - goto cleanup_and_return; - } - intVal = atoi(value); - if ((intVal<0) || (intVal>9)) { - FONT_CATALOG_PRINTF(("failed to parse (or invalid) width (%s)",value)); - goto cleanup_and_return; - } - fce->mWidth = (unsigned short)intVal; - } - else if (STRMATCH(name,"CodePageRange1")) { - if (fce->mCodePageRange1 != 0) { - FONT_CATALOG_PRINTF(("CodePageRange1 defined multiple times (0x%lx, %s)", - fce->mCodePageRange1, value)); - goto cleanup_and_return; - } - num = sscanf(value, "%lx", &uLongVal); - if (num != 1) { - FONT_CATALOG_PRINTF(("failed to parse mCodePageRange1 (%s)",value)); - goto cleanup_and_return; - } - fce->mCodePageRange1 = uLongVal; - } - else if (STRMATCH(name,"CodePageRange2")) { - if (fce->mCodePageRange2 != 0) { - FONT_CATALOG_PRINTF(("CodePageRange2 defined multiple times (0x%lx, %s)", - fce->mCodePageRange2, value)); - goto cleanup_and_return; - } - num = sscanf(value, "%lx", &uLongVal); - if (num != 1) { - FONT_CATALOG_PRINTF(("failed to parse mCodePageRange2 (%s)",value)); - goto cleanup_and_return; - } - fce->mCodePageRange2 = uLongVal; - } - else if (STRMATCH(name,"VendorID")) { - if (fce->mVendorID[0] != '\0') { - FONT_CATALOG_PRINTF(("vendor id defined multiple times (%s, %s)", - fce->mVendorID, value)); - goto cleanup_and_return; - } - memset((char*)fce->mVendorID, 0, sizeof(fce->mVendorID)); - strncpy((char*)fce->mVendorID, value, sizeof(fce->mVendorID)-1); - } - else if (STRMATCH(name,"EmbeddedBitmapHeights")) { - if (fce->mNumEmbeddedBitmaps != 0) { - FONT_CATALOG_PRINTF(("EmbeddedBitmapHeights defined multiple times")); - goto cleanup_and_return; - } - int embeddedBitmapHeights[1024]; - int maxEmbeddedBitmaps = - sizeof(embeddedBitmapHeights)/sizeof(embeddedBitmapHeights[0]); - int numEmbeddedBitmaps = 0; - const char *p = value; - const char *q; - while ((q=strchr(p, ','))) { - intVal = atoi(p); - if (intVal < 1) { - FONT_CATALOG_PRINTF(("failed to parse EmbeddedBitmapHeights(%s)",value)); - goto cleanup_and_return; - } - embeddedBitmapHeights[numEmbeddedBitmaps++] = intVal; - if (numEmbeddedBitmaps >= maxEmbeddedBitmaps) { - FONT_CATALOG_PRINTF(("can only handle %d numEmbeddedBitmaps", - maxEmbeddedBitmaps)); - break; - } - p = q + 1; // point to next height - } - fce->mNumEmbeddedBitmaps = numEmbeddedBitmaps; - if (fce->mNumEmbeddedBitmaps) { - fce->mEmbeddedBitmapHeights = (int*)calloc(fce->mNumEmbeddedBitmaps, - sizeof(int)); - if (!fce->mEmbeddedBitmapHeights) - goto cleanup_and_return; - for (int i=0; imNumEmbeddedBitmaps; i++) - fce->mEmbeddedBitmapHeights[i] = embeddedBitmapHeights[i]; - } - } - else if (STRNMATCH(name,"CCMap:",6)) { - num = sscanf(name+6, "%lx", &uLongVal); - if (num != 1) { - FONT_CATALOG_PRINTF(("failed to parse CCMap address (%s)",name+6)); - goto cleanup_and_return; - } - rslt = ParseCCMapLine(&ccmapObj, uLongVal, value); - if (!rslt) { - FONT_CATALOG_PRINTF(("failed to parse CCMap value (%s)",value)); - goto cleanup_and_return; - } - } - } - - fce->mCCMap = ccmapObj.NewCCMap(); - - if (!fce->mCCMap) { - FONT_CATALOG_PRINTF(("missing char map")); - goto cleanup_and_return; - } - if (!fce->mFamilyName) { - FONT_CATALOG_PRINTF(("missing family name")); - goto cleanup_and_return; - } - if ((fce->mFlags&FCE_FLAGS_ISVALID) && (fce->mFlags == 0)) { - FONT_CATALOG_PRINTF(("missing flags")); - goto cleanup_and_return; - } - if (!fce->mFontFileName) { - FONT_CATALOG_PRINTF(("missing font file name")); - goto cleanup_and_return; - } - if (fce->mMTime == 0) { - FONT_CATALOG_PRINTF(("missing mtime")); - goto cleanup_and_return; - } - if (!fce->mFontType) { - FONT_CATALOG_PRINTF(("missing font type")); - goto cleanup_and_return; - } - if (!fce->mStyleName) { - FONT_CATALOG_PRINTF(("missing style name")); - goto cleanup_and_return; - } - if ((fce->mFlags&FCE_FLAGS_ISVALID) && (fce->mNumGlyphs == 0)) { - FONT_CATALOG_PRINTF(("missing num glyphs")); - goto cleanup_and_return; - } - if (fce->mFlags&FCE_FLAGS_ISVALID - && ((fce->mFlags & FCE_FLAGS_UNICODE) || (fce->mFlags & FCE_FLAGS_SURROGATE)) - && (fce->mNumUsableGlyphs == 0)) { - FONT_CATALOG_PRINTF(("missing num usable glyphs")); - goto cleanup_and_return; - } - - return fce; - -cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontCatalog::NewFceFromSummary failed")); - if (fce->mCCMap) - FreeCCMap(fce->mCCMap); - FREE_IF(fce->mFamilyName); - FREE_IF(fce->mFontFileName); - FREE_IF(fce->mFontType); - FREE_IF(fce->mStyleName); - FREE_IF(fce->mEmbeddedBitmapHeights); - FREE_IF(fce); - return nsnull; -} - -nsFontCatalog * -nsFT2FontCatalog::NewFontCatalog() -{ - nsFontCatalog *fc; - fc = (nsFontCatalog *)calloc(1, sizeof(nsFontCatalog)); - return fc; -} - -PRBool -nsFT2FontCatalog::ParseCCMapLine(nsCompressedCharMap *aCCMapObj, long base, - const char *valString) -{ - int i, j, len; - unsigned int byte; - PRUint32 pagechar = (PRUint32)base; - - // check we have the right number of chars - len = strlen(valString); - if (len != (2*(CCMAP_BITS_PER_PAGE/8))) - return PR_FALSE; - - const char *p = valString; - for (i=0; i<(CCMAP_BITS_PER_PAGE/8); i++) { -#if 0 // scanf is way too slow - int num = sscanf(valString+(2*i), "%2x", &byte); - if (num != 1) - return PR_FALSE; -#else - NS_ASSERTION((*p>='0' && *p<='9') - || (*p>='a' && *p<='f') - || (*p>='A' && *p<='F'), "Invalid ccmap char"); - if (*p <= '9') - byte = *p++ - '0'; - else { - byte = (*p++ & 0x4F) - 'A' + 10; - } - byte <<= 4; - NS_ASSERTION((*p>='0' && *p<='9') - || (*p>='a' && *p<='f') - || (*p>='A' && *p<='F'), "Invalid ccmap char"); - if (*p <= '9') - byte |= *p++ - '0'; - else { - byte |= (*p++ & 0x4F) - 'A' + 10; - } -#endif - if (byte == 0) { - pagechar += 8; - continue; - } - - for (j=0; j<8; j++) { - if (byte & (1<SetChar(pagechar); - pagechar++; - } - } - return PR_TRUE; -} - - -void -nsFT2FontCatalog::PrintCCMap(nsNameValuePairDB *aDB, PRUint16 *aCCMap) -{ - if (!aCCMap) - return; - - PRUint32 page = CCMAP_BEGIN_AT_START_OF_MAP; - while (NextNonEmptyCCMapPage(aCCMap, &page)) { - //FONT_CATALOG_PRINTF(("page starting at 0x%04x has chars", page)); - PrintPageBits(aDB, aCCMap, page); - } -} - -void -nsFT2FontCatalog::PrintFontSummaries(nsNameValuePairDB *aDB, - nsFontCatalog *aFontCatalog) -{ - int i; - nsFontCatalogEntry *fce; - char font_num[30]; - char buf[30]; - - aDB->PutStartGroup("FontSummariesInfo"); - aDB->PutElement("", "#############################"); - aDB->PutElement("", "# Font Summaries #"); - aDB->PutElement("", "#############################"); - aDB->PutElement("", "#"); - sprintf(buf, "%d", aFontCatalog->numFonts); - aDB->PutElement("NumFonts", buf); - aDB->PutEndGroup("FontSummariesInfo"); - for (i=0; inumFonts; i++) { - fce = aFontCatalog->fonts[i]; - sprintf(font_num, "Font_%d", i); - aDB->PutStartGroup(font_num); - aDB->PutElement("FamilyName", fce->mFamilyName); - sprintf(buf, "%08x", fce->mFlags); - aDB->PutElement("Flags", buf); - aDB->PutElement("FontFileName", fce->mFontFileName); - sprintf(buf, "%ld", fce->mMTime); - aDB->PutElement("MTime", buf); - aDB->PutElement("FontType", fce->mFontType); - sprintf(buf, "%d", fce->mFaceIndex); - aDB->PutElement("FaceIndex", buf); - sprintf(buf, "%d", fce->mNumFaces); - aDB->PutElement("NumFaces", buf); - aDB->PutElement("StyleName", fce->mStyleName); - sprintf(buf, "%d", fce->mNumGlyphs); - aDB->PutElement("NumGlyphs", buf); - sprintf(buf, "%d", fce->mNumUsableGlyphs); - aDB->PutElement("NumUsableGlyphs", buf); - sprintf(buf, "%08lx", fce->mFaceFlags); - aDB->PutElement("FaceFlags", buf); - sprintf(buf, "%08lx", fce->mStyleFlags); - aDB->PutElement("StyleFlags", buf); - sprintf(buf, "%d", fce->mWeight); - aDB->PutElement("Weight", buf); - sprintf(buf, "%d", fce->mWidth); - aDB->PutElement("Width", buf); - sprintf(buf, "%08lx", fce->mCodePageRange1); - aDB->PutElement("CodePageRange1", buf); - sprintf(buf, "%08lx", fce->mCodePageRange2); - aDB->PutElement("CodePageRange2", buf); - aDB->PutElement("VendorID", fce->mVendorID); - nsCAutoString embeddedHeightStr(""); - for (int j=0; jmNumEmbeddedBitmaps; j++) { - sprintf(buf, "%d,", fce->mEmbeddedBitmapHeights[j]); - embeddedHeightStr.Append(buf); - } - aDB->PutElement("EmbeddedBitmapHeights", - PromiseFlatCString(embeddedHeightStr).get()); - aDB->PutElement("", "# ccmap"); - - PrintCCMap(aDB, fce->mCCMap); - aDB->PutEndGroup(font_num); - } -} - -void -nsFT2FontCatalog::PrintFontSummaryVersion(nsNameValuePairDB *aDB) -{ - char buf[30]; - - aDB->PutStartGroup(FONT_SUMMARY_VERSION_TAG); - aDB->PutElement("", "#############################"); - aDB->PutElement("", "# Font Summary Version #"); - aDB->PutElement("", "#############################"); - aDB->PutElement("", "#"); - sprintf(buf, "%u.%u.%u", FONT_SUMMARY_VERSION_MAJOR, - FONT_SUMMARY_VERSION_MINOR, - FONT_SUMMARY_VERSION_REV); - aDB->PutElement("Version", buf); - aDB->PutEndGroup(FONT_SUMMARY_VERSION_TAG); -} - -void -nsFT2FontCatalog::PrintPageBits(nsNameValuePairDB *aDB, PRUint16 *aCCMap, - PRUint32 aPageStart) -{ - int i; - PRUint32 pagechar = aPageStart; - char addr[64]; - char buf[64]; - - - nsCAutoString ccmap_line(""); - for (i=0; i<(CCMAP_BITS_PER_PAGE/8); i++) { - unsigned char val = 0; - for (int j=0; j<8; j++) { - if (CCMAP_HAS_CHAR_EXT(aCCMap, pagechar)) { - val |= 1 << j; - } - pagechar++; - } - sprintf(buf, "%02x", val); - ccmap_line.Append(buf); - } - sprintf(addr, "CCMap:0x%04lx", (long)aPageStart); - aDB->PutElement(addr, PromiseFlatCString(ccmap_line).get()); -} - -PRBool -nsFT2FontCatalog::ReadFontDirSummary(const nsACString& aFontSummaryFilename, - nsHashtable* aFontFileNamesHash) -{ - nsNameValuePairDB fc; - int status; - - if (!fc.OpenForRead(aFontSummaryFilename)) { - FONT_CATALOG_PRINTF(("could not open font catalog %s", - PromiseFlatCString(aFontSummaryFilename).get())); - return PR_FALSE; - } - - // - // check the font summary version number - // - status = CheckFontSummaryVersion(&fc); - if (status != FC_FILE_OKAY) - goto cleanup_and_return; - - // - // read font summaries - // - ReadFontSummaries(aFontFileNamesHash, &fc); - - return PR_TRUE; - -cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontCatalog::ReadFontDirSummary failed")); - return PR_FALSE; -} - -int -nsFT2FontCatalog::ReadFontSummaries(nsHashtable* aFontHash, - nsNameValuePairDB *aDB) -{ - - const char *type, *name, *value; - int i, numFonts = 0; - nsFontCatalogEntry *fce = nsnull; - - // - // Get the number of font summaries - // - if (!aDB->GetNextGroup(&type, "FontSummariesInfo")) { - FONT_CATALOG_PRINTF(("file garbled: expected begin=FontSummariesInfo, " - "got %s", type)); - goto cleanup_and_return; - } - while (aDB->GetNextElement(&name, &value) > 0) { - if (strcmp(name, "NumFonts")==0) { - numFonts = atoi(value); - if (numFonts<0) { - FONT_CATALOG_PRINTF(("failed to parse num fonts (%s)", value)); - goto cleanup_and_return; - } - } - } - - for (i=0; imFontFileName); - // Since we are hashing by file name we need to add a FaceIndex - // else we would lose the other ttc faces - if (fce->mFaceIndex != 0) { - // add face num to hash key - nsCAutoString key_str(fce->mFontFileName); - char buf[20]; - sprintf(buf, "/%d", fce->mFaceIndex); - key_str.Append(buf); - key = key_str; - } - FONT_CATALOG_PRINTF(("key = %s", key.GetString())); - aFontHash->Put(&key, (void *)fce); - } - - return numFonts; - -cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontCatalog::ReadFontSummaries failed")); - return 0; -} - -unsigned long -nsFT2FontCatalog::GetRangeLanguage(const nsACString & aLanguage, - PRInt16 aRange) -{ - unsigned long *bit; - if (aLanguage.IsEmpty()) - return 0; - nsCStringKey key(aLanguage); - if (aRange == CPR1) - bit = (unsigned long *)(mRange1Language->Get(&key)); - if (aRange == CPR2) - bit = (unsigned long *)(mRange2Language->Get(&key)); - if (bit) - return *bit; - return 0; -} - -nsFontVendorName sVendorNamesList[] = { - { "2REB", "2Rebels" }, - { "39BC", "Finley's Barcode Fonts" }, - { "3ip", "Three Islands Press" }, - { "918", "RavenType" }, - { "ABC", "Altek Instruments" }, - { "ACUT", "Acute Type" }, - { "ADBE", "Adobe" }, - { "AGFA", "Agfa Monotype" }, - { "ALPH", "Alphameric Broadcast Solutions" }, - { "ALTS", "Altsys (Macromedia)" }, - { "AOP", "An Art of Penguin" }, - { "APOS", "Apostrophic Laboratories" }, - { "APPL", "Apple" }, - { "ARPH", "Arphic Technology" }, - { "ARS", "EN ARS" }, - { "ATEC", "Page Technology Marketing" }, - { "AZLS", "Azalea Software" }, - { "B&H", "Bigelow & Holmes" }, - { "BARS", "CIA (BAR CODES) UK" }, - { "BERT", "Berthold" }, - { "BITM", "Bitmap Software" }, - { "BITS", "Bitstream" }, - { "BLAH", "Mister Bla's Fontworx" }, - { "BORW", "Borware" }, - { "BOYB", "BoyBeaver Fonts" }, - { "BRTC", "Bear Rock Technologies" }, - { "BWFW", "B/W Fontworks" }, - { "C21", "Club 21" }, - { "CAK", "pluginfonts" }, - { "CANO", "Canon" }, - { "CASL", "H.W. Caslon" }, - { "CDAC", "Centre for Development of Advanced Computing"}, - { "CFA", "Computer Fonts Australia" }, - { "CONR", "Connare" }, - { "COOL", "Cool Fonts" }, - { "CORD", "corduroy" }, - { "CTDL", "China Type Designs" }, - { "cwwf", "Computers World Wide/AC Capital Funding" }, - { "DAMA", "Dalton Maag" }, - { "DELV", "Delve Media Arts" }, - { "DFS", "Datascan Font Service" }, - { "DGL", "Digital Graphic Labs foundry" }, - { "DS", "Dainippon Screen" }, - { "DSCI", "Design Science" }, - { "DSST", "Dubina Nikolay" }, - { "DTC", "Digital Typeface" }, - { "DTPS", "DTP-Software" }, - { "dtpT", "dtpTypes" }, - { "DUXB", "Duxbury Systems" }, - { "DYNA", "DynaLab" }, - { "EDGE", "Rivers Edge" }, - { "EFF", "Electronic Font Foundry" }, - { "EFNT", "E Fonts L.L.C." }, - { "ELSE", "Elseware (Hewlett-Packard)" }, - { "EMGR", "Emigre" }, - { "EPSN", "Epson" }, - { "ESIG", "E-Signature" }, - { "EVER", "Everson Typography" }, - { "FBI", "The Font Bureau" }, - { "FCAB", "The Font Cabinet" }, - { "FCAN", "fontage canada" }, - { "FNTF", "Fontfoundry" }, - { "FONT", "Font Source" }, - { "FS", "Formula Solutions" }, - { "FSE", "Font Source Europe" }, - { "FSI", "FSI Fonts und Software" }, - { "FTFT", "FontFont" }, - { "FWRE", "Fontware" }, - { "GALA", "Galápagos Design Group" }, - { "GD", "GD Fonts" }, - { "GF", "GarageFonts" }, - { "GLYF", "Glyph Systems" }, - { "GOAT", "Dingbat Dungeon" }, - { "GOGO", "Fonts-A-Go-Go" }, - { "GPI", "Gamma Productions" }, - { "GRIL", "Grilled cheese" }, - { "HILL", "Hill Systems" }, - { "HL", "High-Logic" }, - { "HOUS", "House Industries" }, - { "HP", "Hewlett-Packard" }, - { "HS", "HermesSOFT" }, - { "HY", "HanYang System" }, - { "IBM", "IBM" }, - { "IDAU", "IDAutomation" }, - { "IDEE", "IDEE TYPOGRAFICA" }, - { "IDF", "International Digital Fonts" }, - { "ILP", "Indigenous Language Project" }, - { "IMPR", "Impress" }, - { "INVC", "Invoice Central" }, - { "ITF", "International TypeFounders" }, - { "KATF", "Kingsley/ATF" }, - { "KUBA", "Kuba Tatarkiewicz" }, - { "LARA", "Larabiefonts" }, - { "LEAF", "Interleaf" }, - { "LETR", "Letraset" }, - { "LGX", "Logix Research Institute" }, - { "LING", "Linguist's Software" }, - { "LINO", "Linotype" }, - { "LP", "LetterPerfect Fonts" }, - { "LTRX", "Lighttracks" }, - { "MACR", "Macromedia" }, - { "MATS", "Match Fonts" }, - { "MC", "Cerajewski Computer Consulting" }, - { "MEIR", "Meir Sadan" }, - { "MF", "Magic Fonts" }, - { "MFNT", "Masterfont" }, - { "MILL", "Millan" }, - { "MJ", "Majus" }, - { "MJR", "Majur" }, - { "MLGC", "Micrologic Software" }, - { "MONO", "Agfa Monotype" }, - { "MOON", "Moonlight Type and Technolog" }, - { "MS", "Microsoft" }, - { "MSCR", "Majus" }, - { "MSE", "MSE-iT" }, - { "MT", "Agfa Monotype" }, - { "MTY", "Motoya" }, - { "MUTF", "Murasu Systems Sdn. Bhd" }, - { "MYFO", "MyFonts" }, - { "NB", "No Bodoni Typography" }, - { "NDTC", "Neufville Digital" }, - { "NEC", "NEC" }, - { "NIS", "NIS" }, - { "ORBI", "Orbit Enterprises" }, - { "P22", "P22" }, - { "PARA", "ParaType" }, - { "PDWX", "Parsons Design Workx" }, - { "PF", "Phil's Fonts" }, - { "PLAT", "PLATINUM technology" }, - { "PRFS", "Production First Software" }, - { "PSY", "PSY/OPS" }, - { "PTF", "Porchez Typofonderie" }, - { "PTMI", "Page Technology Marketing" }, - { "PYRS", "Pyrus" }, - { "QMSI", "QMS/Imagen" }, - { "RKFN", "R K Fonts" }, - { "robo", "Buro Petr van Blokland" }, - { "RRT", "Red Rooster Typefounders" }, - { "RUDY", "RudynFluffy" }, - { "RYOB", "Ryobi" }, - { "SAX", "s.a.x. Software" }, - { "Sean", "The FontSite" }, - { "SFUN", "Software Union" }, - { "SG", "Scooter Graphics" }, - { "SHFT", "Shift" }, - { "SIG", "Signature Software" }, - { "SIL", "SIL International" }, - { "SIT", "Summit Information Technologies" }, - { "skz", "Celtic Lady's Fonts" }, - { "SN", "SourceNet" }, - { "SOHO", "Soft Horizons" }, - { "SOS", "Standing Ovations Software" }, - { "STF", "Brian Sooy + Sooy Type Foundry" }, - { "SUNW", "sunwalk fontworks" }, - { "SWFT", "Swfte International" }, - { "SYN", "SynFonts" }, - { "SYRC", "Syriac Computing Institute" }, - { "TDR", "Tansin A. Darcos" }, - { "TERM", "Terminal Design" }, - { "TF", "Treacyfaces / Headliners" }, - { "TILD", "Tilde, SIA" }, - { "TIRO", "Tiro Typeworks" }, - { "TMF", "The MicroFoundry" }, - { "TPTC", "Test Pilot Collective" }, - { "TR", "Type Revivals" }, - { "TS", "TamilSoft" }, - { "TTG", "Twardoch Typography" }, - { "TYPE", "TypeGroup" }, - { "TYPO", "Typodermic" }, - { "UA", "UnAuthorized Type" }, - { "UNKN", "Unknown Vendor" }, - { "URW", "URW++" }, - { "UT", "Unitype" }, - { "VKP", "Vijay K. Patel" }, - { "VLKF", "Visualogik Technology & Design" }, - { "VOG", "Martin Vogel" }, - { "VROM", "Vladimir Romanov" }, - { "VT", "VISUALTYPE SRL" }, - { "WASP", "Wasp barcode" }, - { "WM", "Webmakers India" }, - { "XFC", "Xerox Font Services" }, - { "Y&Y", "Y&Y" }, - { "ZeGr", "Zebra Font Factory" }, - { "zeta", "Tangram Studio" }, - { "ZSFT", "Zsoft" }, - { nsnull, nsnull }, -}; - - -// TODO: what TT_OS2_CPR1_OEM standard for. use "oem" temporarily. -nsulCodePageRangeLanguage ulCodePageRange1Language[] = { -{ TT_OS2_CPR1_LATIN1 | TT_OS2_CPR1_MAC_ROMAN, "x-western" }, -{ TT_OS2_CPR1_LATIN2, "x-central-euro" }, -{ TT_OS2_CPR1_CYRILLIC, "x-cyrillic" }, -{ TT_OS2_CPR1_GREEK, "el" }, -{ TT_OS2_CPR1_TURKISH, "tr" }, -{ TT_OS2_CPR1_HEBREW, "he" }, -{ TT_OS2_CPR1_ARABIC, "ar" }, -{ TT_OS2_CPR1_BALTIC, "x-baltic" }, -{ TT_OS2_CPR1_VIETNAMESE, "vietnamese" }, -{ TT_OS2_CPR1_THAI, "th" }, -{ TT_OS2_CPR1_JAPANESE, "ja" }, -{ TT_OS2_CPR1_CHINESE_SIMP, "zh-cn" }, -{ TT_OS2_CPR1_KO_WANSUNG | TT_OS2_CPR1_KO_JOHAB, "ko" }, -{ TT_OS2_CPR1_CHINESE_TRAD, "zh-tw" }, -{ TT_OS2_CPR1_OEM, "oem" }, -{ TT_OS2_CPR1_SYMBOL, "symbol" }, -{ 0, nsnull }, -}; - -nsulCodePageRangeLanguage ulCodePageRange2Language[] = { -{ TT_OS2_CPR2_GREEK | TT_OS2_CPR2_GREEK_437G, "el" }, -{ TT_OS2_CPR2_RUSSIAN, "x-cyrillic" }, -{ TT_OS2_CPR2_NORDIC, "x-western" }, -{ TT_OS2_CPR2_ARABIC | TT_OS2_CPR2_ARABIC_708, "ar" }, -{ TT_OS2_CPR2_CA_FRENCH, "x-western" }, -{ TT_OS2_CPR2_HEBREW, "he" }, -{ TT_OS2_CPR2_ICELANDIC, "icelandic" }, -{ TT_OS2_CPR2_PORTUGESE, "x-western" }, -{ TT_OS2_CPR2_TURKISH, "tr" }, -{ TT_OS2_CPR2_CYRILLIC, "x-cyrillic" }, -{ TT_OS2_CPR2_LATIN2, "x-central-euro" }, -{ TT_OS2_CPR2_BALTIC, "x-baltic" }, -{ TT_OS2_CPR2_WE_LATIN1 || TT_OS2_CPR2_US, "x-western" }, -{ 0, nsnull }, -}; -#endif /* #if (!defined(MOZ_ENABLE_FREETYPE2)) */ diff --git a/gfx/src/x11shared/nsFT2FontCatalog.h b/gfx/src/x11shared/nsFT2FontCatalog.h deleted file mode 100644 index 109a045b2bcc..000000000000 --- a/gfx/src/x11shared/nsFT2FontCatalog.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef NS_FT2_FONT_CATALOG_H -#define NS_FT2_FONT_CATALOG_H - -#include "gfx-config.h" -#include "nsIFontCatalogService.h" - -#if (defined(MOZ_ENABLE_FREETYPE2)) -#include "nsFreeType.h" -#include "nsICharRepresentable.h" -#include "nsCompressedCharMap.h" - -#include "nsString.h" -#include "nsIPref.h" -#include "nsNameValuePairDB.h" -#include "nsICharsetConverterManager.h" - -// -// To limit the potential for namespace collision we limit the -// number of Moz files that include FreeType's include (and hence -// have FreeType typedefs, macros, and defines). -// -struct FT_LibraryRec_; -typedef signed long FT_Long; -typedef unsigned short FT_UShort; - -#define PUBLIC_FONT_SUMMARY_NAME NS_LITERAL_CSTRING(".mozilla_font_summary.ndb") -#define FONT_SUMMARIES_SUBDIR NS_LITERAL_CSTRING("catalog") -#define FONT_DOWNLOAD_SUBDIR NS_LITERAL_CSTRING("fonts") -#define FONT_SUMMARIES_EXTENSION NS_LITERAL_CSTRING(".ndb") -#define FONT_SUMMARY_VERSION_TAG "FontSummaryVersion" -#define FONT_SUMMARY_VERSION_MAJOR 1 -#define FONT_SUMMARY_VERSION_MINOR 0 -#define FONT_SUMMARY_VERSION_REV 0 - - -#define FC_FILE_OKAY 0 -#define FC_FILE_GARBLED 1 -#define FC_FILE_MODIFIED 2 - -#define STRMATCH(s1,s2) (strcmp((s1),(s2))==0) -#define STRNMATCH(s1,s2,l) (strncmp((s1),(s2),(l))==0) -#define STRCASEMATCH(s1,s2) (strcasecmp((s1),(s2))==0) - -typedef struct { - const char *mDirName; // encoded in the native charset -} nsDirCatalogEntry; - -#define CPR1 1 // designate CodePageRange1 to use for "GetRangeLanguage" -#define CPR2 2 // designate CodePageRange2 to use for "GetRangeLanguage" - -typedef struct { - nsFontCatalogEntry **fonts; - int numFonts; - int numSlots; -} nsFontCatalog; - -typedef struct { - nsDirCatalogEntry **dirs; - int numDirs; - int numSlots; -} nsDirCatalog; - -typedef struct { - const char *vendorID; - const char *vendorName; -} nsFontVendorName; - -typedef struct { - unsigned long bit; - const char *language; -} nsulCodePageRangeLanguage; - -#endif - -class nsFT2FontCatalog : public nsIFontCatalogService { -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIFONTCATALOGSERVICE - - nsFT2FontCatalog(); - virtual ~nsFT2FontCatalog(); - -#if (defined(MOZ_ENABLE_FREETYPE2)) - - void FreeGlobals(); - PRBool InitGlobals(FT_LibraryRec_ *); - void GetFontNames(const nsACString & aFamilyName, - const nsACString & aLanguage, - PRUint16 aWeight, - PRUint16 aWidth, - PRUint16 aSlant, - PRUint16 aSpacing, - nsFontCatalog* aFC); - static const char* GetFileName(nsFontCatalogEntry *aFce); - static const char* GetFamilyName(nsFontCatalogEntry *aFce); - static PRInt32* GetEmbeddedBitmapHeights(nsFontCatalogEntry *aFce); - static PRInt32 GetFaceIndex(nsFontCatalogEntry *aFce); - static PRInt32 GetNumEmbeddedBitmaps(nsFontCatalogEntry *aFce); - static const char* GetFoundry(nsFontCatalogEntry *aFce); - -protected: - static void AddDir(nsDirCatalog *dc, nsDirCatalogEntry *dir); - PRBool AddFceIfCurrent(const char*, nsHashtable*, PRInt64, nsFontCatalog*); - void AddFont(nsFontCatalog *fc, nsFontCatalogEntry *fce); - int CheckFontSummaryVersion(nsNameValuePairDB *aDB); -#ifdef DEBUG - void DumpFontCatalog(nsFontCatalog *fc); - void DumpFontCatalogEntry(nsFontCatalogEntry *); -#endif - void FixUpFontCatalog(nsFontCatalog *fc); - static PRBool FreeFceHashEntry(nsHashKey* aKey, void* aData, void* aClosure); - void FreeFontCatalog(nsFontCatalog *fc); - static void FreeFontCatalogEntry(nsFontCatalogEntry *); - void FreeDirCatalog(nsDirCatalog *dc); - void FreeDirCatalogEntry(nsDirCatalogEntry *); - static void GetDirsPrefEnumCallback(const char* aName, void* aClosure); - int GetFontCatalog(FT_LibraryRec_*, nsFontCatalog *, nsDirCatalog *); - PRBool GetFontSummaryName(const nsACString &, const nsACString &, - nsACString &, nsACString &); - unsigned long GetRangeLanguage(const nsACString &, PRInt16 aRange); - PRBool HandleFontDir(FT_LibraryRec_ *, nsFontCatalog *, - const nsACString &, const nsACString &); - void HandleFontFile(FT_LibraryRec_ *, nsFontCatalog *, const char*); - PRBool IsSpace(FT_Long); - nsDirCatalog *NewDirCatalog(); - nsFontCatalogEntry* NewFceFromFontFile(FT_LibraryRec_*, const char*,int,int*); - nsFontCatalogEntry* NewFceFromSummary(nsNameValuePairDB *aDB); - nsFontCatalog *NewFontCatalog(); - PRBool ReadFontDirSummary(const nsACString&, nsHashtable*); - PRBool ParseCCMapLine(nsCompressedCharMap*,long,const char*); - void PrintCCMap(nsNameValuePairDB *aDB, PRUint16 *aCCMap); - void PrintFontSummaries(nsNameValuePairDB *, nsFontCatalog *); - void PrintFontSummaryVersion(nsNameValuePairDB *aDB); - void PrintPageBits(nsNameValuePairDB*,PRUint16*,PRUint32); - int ReadFontSummaries(nsHashtable*, nsNameValuePairDB *); - - static nsIPref* sPref; - nsFontCatalog *mFontCatalog; - - PRPackedBool mIsNewCatalog; - static nsHashtable *sVendorNames; - nsHashtable *mRange1Language; - nsHashtable *mRange2Language; - PRBool mAvailableFontCatalogService; - nsCOMPtr mFt2; -#endif -}; - -#endif /* NS_FT2_FONT_CATALOG_H */ - diff --git a/gfx/src/x11shared/nsFT2FontNode.cpp b/gfx/src/x11shared/nsFT2FontNode.cpp deleted file mode 100644 index 307102da5e7c..000000000000 --- a/gfx/src/x11shared/nsFT2FontNode.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * Louie Zhao - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "gfx-config.h" -#include "nsFT2FontNode.h" -#include "nsFontDebug.h" - -#if (!defined(MOZ_ENABLE_FREETYPE2)) - -void nsFT2FontNode::FreeGlobals() {} - -nsresult nsFT2FontNode::InitGlobals() -{ - FREETYPE_FONT_PRINTF(("freetype not compiled in")); - NS_WARNING("freetype not compiled in"); - return NS_OK; -} - -void nsFT2FontNode::GetFontNames(const char* aPattern, - nsFontNodeArray* aNodes) {} - -#else - -#include "nsFreeType.h" -#include "nsFontFreeType.h" -#include "nsIServiceManager.h" -#include "nsIMutableArray.h" -#include "nsArrayUtils.h" - -nsHashtable* nsFT2FontNode::mFreeTypeNodes = nsnull; -PRBool nsFT2FontNode::sInited = PR_FALSE; -nsIFontCatalogService* nsFT2FontNode::sFcs = nsnull; - -void -nsFT2FontNode::FreeGlobals() -{ - NS_IF_RELEASE(sFcs); - - if (mFreeTypeNodes) { - mFreeTypeNodes->Reset(FreeNode, nsnull); - delete mFreeTypeNodes; - mFreeTypeNodes = nsnull; - } - sInited = PR_FALSE; -} - -nsresult -nsFT2FontNode::InitGlobals() -{ - NS_ASSERTION(sInited==PR_FALSE, - "nsFT2FontNode::InitGlobals called more than once"); - - sInited = PR_TRUE; - - nsresult rv = ::CallGetService("@mozilla.org/gfx/xfontcatalogservice;1", - &sFcs); - - if (NS_FAILED(rv)) { - NS_ERROR("Font Catalog Service init failed\n"); - return NS_ERROR_FAILURE; - } - - mFreeTypeNodes = new nsHashtable(); - if (!mFreeTypeNodes) - return NS_ERROR_FAILURE; - - LoadNodeTable(); - WeightTableInitCorrection(nsFreeTypeFont::sLinearWeightTable, - nsFreeType2::gAATTDarkTextMinValue, - nsFreeType2::gAATTDarkTextGain); - - return NS_OK; -} - -void -nsFT2FontNode::GetFontNames(const char* aPattern, nsFontNodeArray* aNodes) -{ - int j; - PRBool rslt; - PRUint32 count, i; - char *pattern, *foundry, *family, *charset, *encoding; - const char *charSetName; - nsFontNode *node; - nsCOMPtr arrayFC; - nsCAutoString familyTmp, languageTmp; - - FONT_CATALOG_PRINTF(("looking for FreeType font matching %s", aPattern)); - nsCAutoString patt(aPattern); - ToLowerCase(patt); - pattern = strdup(patt.get()); - NS_ASSERTION(pattern, "failed to copy pattern"); - if (!pattern) - goto cleanup_and_return; - - rslt = ParseXLFD(pattern, &foundry, &family, &charset, &encoding); - if (!rslt) - goto cleanup_and_return; - - // unable to handle "name-charset-*" - if (charset && !encoding) { - goto cleanup_and_return; - } - - if (family) - familyTmp.Assign(family); - - sFcs->GetFontCatalogEntries(familyTmp, languageTmp, 0, 0, 0, 0, - getter_AddRefs(arrayFC)); - if (!arrayFC) - goto cleanup_and_return; - arrayFC->GetLength(&count); - for (i = 0; i < count; i++) { - nsCOMPtr fce = do_QueryElementAt(arrayFC, i); - if (!fce) - continue; - nsCAutoString foundryName, familyName; - PRUint32 flags, codePageRange1, codePageRange2; - PRUint16 weight, width; - fce->GetFamilyName(familyName); - fce->GetFlags(&flags); - fce->GetWidth(&width); - fce->GetWeight(&weight); - fce->GetCodePageRange1(&codePageRange1); - fce->GetCodePageRange2(&codePageRange2); - if (!charset) { // get all encoding - FONT_CATALOG_PRINTF(("found FreeType %s-%s-*-*", foundryName.get(), - familyName.get())); - for (j=0; j<32; j++) { - unsigned long bit = 1 << j; - if (bit & codePageRange1) { - charSetName = nsFreeType2::GetRange1CharSetName(bit); - NS_ASSERTION(charSetName, "failed to get charset name"); - if (!charSetName) - continue; - node = LoadNode(fce, charSetName, aNodes); - } - if (bit & codePageRange2) { - charSetName = nsFreeType2::GetRange2CharSetName(bit); - if (!charSetName) - continue; - LoadNode(fce, charSetName, aNodes); - } - } - if (foundryName.IsEmpty() && !familyName.IsEmpty() && flags&FCE_FLAGS_SYMBOL) { - // the "registry-encoding" is not used but LoadNode will fail without - // some value for this - LoadNode(fce, "symbol-fontspecific", aNodes); - } - } - - if (charset && encoding) { // get this specific encoding - PRUint32 cpr1_bits, cpr2_bits; - nsCAutoString charsetName(charset); - charsetName.Append('-'); - charsetName.Append(encoding); - CharSetNameToCodeRangeBits(charsetName.get(), &cpr1_bits, &cpr2_bits); - if (!(cpr1_bits & codePageRange1) - && !(cpr2_bits & codePageRange2)) - continue; - FONT_CATALOG_PRINTF(("found FreeType -%s-%s-%s", - familyName.get(),charset,encoding)); - LoadNode(fce, charsetName.get(), aNodes); - } - } - - FREE_IF(pattern); - return; - -cleanup_and_return: - FONT_CATALOG_PRINTF(("nsFT2FontNode::GetFontNames failed")); - FREE_IF(pattern); - return; -} - -nsFontNode* -nsFT2FontNode::LoadNode(nsITrueTypeFontCatalogEntry *aFce, - const char *aCharSetName, - nsFontNodeArray* aNodes) -{ - nsFontCharSetMap *charSetMap = GetCharSetMap(aCharSetName); - if (!charSetMap->mInfo) { - return nsnull; - } - nsCAutoString nodeName, familyName; - aFce->GetVendorID(nodeName); - aFce->GetFamilyName(familyName); - - nodeName.Append('-'); - nodeName.Append(familyName); - nodeName.Append('-'); - nodeName.Append(aCharSetName); - nsCStringKey key(nodeName); - nsFontNode* node = (nsFontNode*) mFreeTypeNodes->Get(&key); - if (!node) { - node = new nsFontNode; - if (!node) { - return nsnull; - } - mFreeTypeNodes->Put(&key, node); - node->mName = nodeName; - nsFontCharSetMap *charSetMap = GetCharSetMap(aCharSetName); - node->mCharSetInfo = charSetMap->mInfo; - } - - PRInt64 styleFlags; - PRUint16 fceWeight, fceWidth; - aFce->GetStyleFlags(&styleFlags); - aFce->GetWidth(&fceWidth); - aFce->GetWeight(&fceWeight); - - int styleIndex; - if (styleFlags & FT_STYLE_FLAG_ITALIC) - styleIndex = NS_FONT_STYLE_ITALIC; - else - styleIndex = NS_FONT_STYLE_NORMAL; - nsFontStyle* style = node->mStyles[styleIndex]; - if (!style) { - style = new nsFontStyle; - if (!style) { - return nsnull; - } - node->mStyles[styleIndex] = style; - } - - int weightIndex = WEIGHT_INDEX(fceWeight); - nsFontWeight* weight = style->mWeights[weightIndex]; - if (!weight) { - weight = new nsFontWeight; - if (!weight) { - return nsnull; - } - style->mWeights[weightIndex] = weight; - } - - nsFontStretch* stretch = weight->mStretches[fceWidth]; - if (!stretch) { - stretch = new nsFontStretch; - if (!stretch) { - return nsnull; - } - weight->mStretches[fceWidth] = stretch; - } - if (!stretch->mFreeTypeFaceID) { - stretch->mFreeTypeFaceID = aFce; - } - if (aNodes) { - int i, n, found = 0; - n = aNodes->Count(); - for (i=0; iGetElement(i) == node) { - found = 1; - } - } - if (!found) { - aNodes->AppendElement(node); - } - } - return node; -} - -PRBool -nsFT2FontNode::LoadNodeTable() -{ - int j; - nsCOMPtr arrayFC; - nsCAutoString family, language; - sFcs->GetFontCatalogEntries(family, language, 0, 0, 0, 0, - getter_AddRefs(arrayFC)); - if (!arrayFC) - return PR_FALSE; - PRUint32 count, i; - arrayFC->GetLength(&count); - for (i = 0; i < count; i++) { - const char *charsetName; - nsCOMPtr fce = do_QueryElementAt(arrayFC, i); - if (!fce) - continue; - PRUint32 flags, codePageRange1, codePageRange2; - PRUint16 weight, width; - fce->GetFlags(&flags); - fce->GetWidth(&width); - fce->GetWeight(&weight); - fce->GetCodePageRange1(&codePageRange1); - fce->GetCodePageRange2(&codePageRange2); - if ((!flags&FCE_FLAGS_ISVALID) - || (weight < 100) || (weight > 900) || (width > 8)) - continue; - for (j=0; j<32; j++) { - unsigned long bit = 1 << j; - if (!(bit & codePageRange1)) - continue; - charsetName = nsFreeType2::GetRange1CharSetName(bit); - NS_ASSERTION(charsetName, "failed to get charset name"); - if (!charsetName) - continue; - LoadNode(fce, charsetName, nsnull); - } - for (j=0; j<32; j++) { - unsigned long bit = 1 << j; - if (!(bit & codePageRange2)) - continue; - charsetName = nsFreeType2::GetRange2CharSetName(bit); - if (!charsetName) - continue; - LoadNode(fce, charsetName, nsnull); - } - } - return PR_TRUE; -} - -// -// Parse XLFD -// The input is a typical XLFD string. -// -// the XLFD entries look like this: -// -adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1 -// -adobe-courier-medium-r-*-*-12-*-*-*-*-*-*-* -// -// the fields are: -// -foundry-family-weight-slant-width-style-pixelsize-pointsize- -// resolution_x-resolution_y-spacing-avg_width-registry-encoding -// -// see ftp://ftp.x.org/pub/R6.4/xc/doc/hardcopy/XLFD -// -PRBool -nsFT2FontNode::ParseXLFD(char *aPattern, char** aFoundry, char** aFamily, - char** aCharset, char** aEncoding) -{ - char *p; - int i; - - *aFoundry = nsnull; - *aFamily = nsnull; - *aCharset = nsnull; - *aEncoding = nsnull; - - // start of pattern - p = aPattern; - NS_ASSERTION(*p == '-',"garbled pattern: does not start with a '-'"); - if (*p++ != '-') - return PR_FALSE; - - // foundry - NS_ASSERTION(*p,"garbled pattern: unexpected end of pattern"); - if (!*p) - return PR_FALSE; - if (*p == '*') - *aFoundry = nsnull; - else - *aFoundry = p; - while (*p && (*p!='-')) - p++; - if (!*p) - return PR_TRUE; // short XLFD - NS_ASSERTION(*p == '-',"garbled pattern: cannot find end of foundry"); - *p++ = '\0'; - - // family - if (!*p) - return PR_TRUE; // short XLFD - if (*p == '*') - *aFamily = nsnull; - else - *aFamily = p; - while (*p && (*p!='-')) - p++; - if (!*p) - return PR_TRUE; // short XLFD - NS_ASSERTION(*p == '-',"garbled pattern: cannot find end of family"); - *p++ = '\0'; - - // skip forward to charset - for (i=0; i<10; i++) { - while (*p && (*p!='-')) - p++; - if (!*p) - return PR_TRUE; // short XLFD - *p++ = '\0'; - } - - // charset - NS_ASSERTION(*p,"garbled pattern: unexpected end of pattern"); - if (!*p) - return PR_FALSE; - if (*p == '*') - *aCharset = nsnull; - else - *aCharset = p; - while (*p && (*p!='-')) - p++; - if (!*p) - return PR_TRUE; // short XLFD - NS_ASSERTION(*p == '-',"garbled pattern: cannot find end of charset"); - *p++ = '\0'; - - // encoding - NS_ASSERTION(*p,"garbled pattern: unexpected end of pattern"); - if (!*p) - return PR_FALSE; - if (*p == '*') - *aEncoding = nsnull; - else - *aEncoding = p; - while (*p && (*p!='-')) - p++; - if (*p) - return PR_TRUE; // short XLFD - return PR_TRUE; -} - -#endif - diff --git a/gfx/src/x11shared/nsFT2FontNode.h b/gfx/src/x11shared/nsFT2FontNode.h deleted file mode 100644 index f219e88d50de..000000000000 --- a/gfx/src/x11shared/nsFT2FontNode.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * Louie Zhao - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef NS_FT2_FONT_NODE_H -#define NS_FT2_FONT_NODE_H - -#include "nsFontMetricsGTK.h" - -class nsFT2FontNode { -public: - static void FreeGlobals(); - static nsresult InitGlobals(); - static void GetFontNames(const char* aPattern, nsFontNodeArray* aNodes); - -#if (defined(MOZ_ENABLE_FREETYPE2)) -protected: - static PRBool ParseXLFD(char *, char**, char**, char**, char**); - static nsFontNode* LoadNode(nsITrueTypeFontCatalogEntry*, - const char*, - nsFontNodeArray*); - static PRBool LoadNodeTable(); - static nsHashtable *mFreeTypeNodes; - static PRBool sInited; - static nsIFontCatalogService* sFcs; -#endif //MOZ_ENABLE_FREETYPE2 - -}; - -#endif - diff --git a/gfx/src/x11shared/nsFontDebug.h b/gfx/src/x11shared/nsFontDebug.h deleted file mode 100644 index e49b647886d7..000000000000 --- a/gfx/src/x11shared/nsFontDebug.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * Louie Zhao - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef nsFontDebug_h__ -#define nsFontDebug_h__ - -#define NS_FONT_DEBUG_LOAD_FONT 0x01 -#define NS_FONT_DEBUG_CALL_TRACE 0x02 -#define NS_FONT_DEBUG_FIND_FONT 0x04 -#define NS_FONT_DEBUG_SIZE_FONT 0x08 -#define NS_FONT_DEBUG_SCALED_FONT 0x10 -#define NS_FONT_DEBUG_BANNED_FONT 0x20 -#define NS_FONT_DEBUG_FONT_CATALOG 0x100 -#define NS_FONT_DEBUG_FONT_SCAN 0x200 -#define NS_FONT_DEBUG_FREETYPE_FONT 0x400 -#define NS_FONT_DEBUG_FREETYPE_GRAPHICS 0x800 - -#undef NS_FONT_DEBUG -#define NS_FONT_DEBUG 1 -#ifdef NS_FONT_DEBUG - -# define DEBUG_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, 0xFFFF) - -# define DEBUG_PRINTF_MACRO(x, type) \ - PR_BEGIN_MACRO \ - if (gFontDebug & (type)) { \ - printf x ; \ - printf(", %s %d\n", __FILE__, __LINE__); \ - } \ - PR_END_MACRO -#else -# define DEBUG_PRINTF_MACRO(x, type) \ - PR_BEGIN_MACRO \ - PR_END_MACRO -#endif - -#define FIND_FONT_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, NS_FONT_DEBUG_FIND_FONT) - -#define SIZE_FONT_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, NS_FONT_DEBUG_SIZE_FONT) - -#define SCALED_FONT_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, NS_FONT_DEBUG_SCALED_FONT) - -#define BANNED_FONT_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, NS_FONT_DEBUG_BANNED_FONT) - -#define FONT_CATALOG_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, NS_FONT_DEBUG_FONT_CATALOG) - -#define FONT_SCAN_PRINTF(x) \ - PR_BEGIN_MACRO \ - if (gFontDebug & NS_FONT_DEBUG_FONT_SCAN) { \ - printf x ; \ - fflush(stdout); \ - } \ - PR_END_MACRO - -#define FREETYPE_FONT_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, NS_FONT_DEBUG_FREETYPE_FONT) - -#ifdef MOZ_ENABLE_FREETYPE2 -extern PRUint32 gFontDebug; -#endif - -#endif - diff --git a/gfx/src/x11shared/nsFontFreeType.cpp b/gfx/src/x11shared/nsFontFreeType.cpp deleted file mode 100644 index ed17f7108189..000000000000 --- a/gfx/src/x11shared/nsFontFreeType.cpp +++ /dev/null @@ -1,967 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * Louie Zhao - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifdef DEBUG -// set this to 1 to have the code draw the bounding boxes -#define DEBUG_SHOW_GLYPH_BOX 0 -#endif - -#include "gfx-config.h" -#include "nsFontFreeType.h" -#include "nsUnicharUtils.h" - -#if (!defined(MOZ_ENABLE_FREETYPE2)) - -nsFreeTypeFont * -nsFreeTypeFont::NewFont(nsITrueTypeFontCatalogEntry *, PRUint16, const char *) -{ - return nsnull; -} - -#else - -#include "nsX11AlphaBlend.h" -#include "nsAntiAliasedGlyph.h" -#include "nsFontDebug.h" -#include "nsIServiceManager.h" - -// macros to handle FreeType2 16.16 numbers -#define FT_16_16_TO_REG(x) ((x)>>16) - -#define IMAGE_BUFFER_SIZE 2048 - -PRUint32 deltaMicroSeconds(PRTime aStartTime, PRTime aEndTime); -void GetFallbackGlyphMetrics(FT_BBox *aBoundingBox, FT_Face aFace); - -PRUint8 nsFreeTypeFont::sLinearWeightTable[256]; - -// -// class nsFreeTypeXImage definition -// -class nsFreeTypeXImage : public nsFreeTypeFont { -public: - nsFreeTypeXImage(nsITrueTypeFontCatalogEntry *aFaceID, PRUint16 aPixelSize, - const char *aName); - gint DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength); -protected: - nsFreeTypeXImage(); -}; - -// -// class nsFreeTypeXImageSBC (Single Byte Converter) definition -// -class nsFreeTypeXImageSBC : public nsFreeTypeXImage { -public: - nsFreeTypeXImageSBC(nsITrueTypeFontCatalogEntry *aFaceID, - PRUint16 aPixelSize, const char *aName); -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); -#endif - - virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength); - virtual gint DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength); -protected: - nsFreeTypeXImageSBC(); -}; - -#ifdef ENABLE_TIME_MACROS -PRUint32 -deltaMicroSeconds(PRTime aStartTime, PRTime aEndTime) -{ - PRUint32 delta; - PRUint64 loadTime64; - - LL_SUB(loadTime64, aEndTime, aStartTime); - LL_L2UI(delta, loadTime64); - - return delta; -} -#endif - -// -// class nsFreeTypeFont data/functions -// -nsFreeTypeFont::nsFreeTypeFont() -{ - NS_ERROR("should never call nsFreeTypeFont::nsFreeTypeFont"); -} - -nsFreeTypeFont * -nsFreeTypeFont::NewFont(nsITrueTypeFontCatalogEntry *aFaceID, - PRUint16 aPixelSize, const char *aName) -{ - // Make sure FreeType is available - nsresult rv; - nsCOMPtr ft2 = do_GetService(NS_FREETYPE2_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - NS_ERROR("FreeType2 routines not available"); - return nsnull; - } - - // for now we only support ximage (XGetImage/alpha-blend/XPutImage) display - // when we support XRender then we will need to test if it is - // available and if so use it since it is faster than ximage. - PRBool ximage = PR_TRUE; - PRBool render = PR_FALSE; - nsFreeTypeFont *ftfont; - nsCAutoString familyName; - aFaceID->GetFamilyName(familyName); - nsTTFontFamilyEncoderInfo *ffei = - nsFreeType2::GetCustomEncoderInfo(familyName.get()); - if (ximage) { - if (ffei) { - ftfont = new nsFreeTypeXImageSBC(aFaceID, aPixelSize, aName); - } - else { - ftfont = new nsFreeTypeXImage(aFaceID, aPixelSize, aName); - } - return ftfont; - } - else if (render) { - NS_ERROR("need to construct a render type FreeType object"); - return nsnull; - } - NS_ERROR("need to construct other type FreeType objects"); - return nsnull; -} - -FT_Face -nsFreeTypeFont::getFTFace() -{ - FT_Face face = nsnull; - FTC_Manager mgr; - nsresult rv; - mFt2->GetFTCacheManager(&mgr); - rv = mFt2->ManagerLookupSize(mgr, &mImageDesc.font, &face, nsnull); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get face/size"); - if (NS_FAILED(rv)) - return nsnull; - return face; -} - -nsFreeTypeFont::nsFreeTypeFont(nsITrueTypeFontCatalogEntry *aFaceID, - PRUint16 aPixelSize, const char *aName) -{ - PRBool anti_alias = PR_TRUE; - PRBool embedded_bimap = PR_FALSE; - mFaceID = aFaceID; - mPixelSize = aPixelSize; - mImageDesc.font.face_id = (void*)mFaceID; - mImageDesc.font.pix_width = aPixelSize; - mImageDesc.font.pix_height = aPixelSize; - mImageDesc.image_type = 0; - - if (aPixelSize < nsFreeType2::gAntiAliasMinimum) { - mImageDesc.image_type |= ftc_image_mono; - anti_alias = PR_FALSE; - } - - if (nsFreeType2::gFreeType2Autohinted) - mImageDesc.image_type |= ftc_image_flag_autohinted; - - if (nsFreeType2::gFreeType2Unhinted) - mImageDesc.image_type |= ftc_image_flag_unhinted; - - PRUint32 num_embedded_bitmaps, i; - PRInt32* embedded_bitmapheights; - mFaceID->GetEmbeddedBitmapHeights(&num_embedded_bitmaps, - &embedded_bitmapheights); - // check if we have an embedded bitmap - if (aPixelSize <= nsFreeType2::gEmbeddedBitmapMaximumHeight) { - if (num_embedded_bitmaps) { - for (i=0; iGetCCMap(&size, &mCCMap); -#ifdef NS_FONT_DEBUG_LOAD_FONT - nsCAutoString fileName; - mFaceID->GetFileName(fileName); - if (gFontDebug & NS_FONT_DEBUG_LOAD_FONT) { - printf("loaded \"%s\", size=%d, filename=%s\n", - mName, mSize, fileName.get()); - } -#endif -} - -nsFreeTypeFont::~nsFreeTypeFont() -{ -} - -#ifdef MOZ_MATHML -nsresult -nsFreeTypeFont::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - return doGetBoundingMetrics(aString, aLength, - &aBoundingMetrics.leftBearing, - &aBoundingMetrics.rightBearing, - &aBoundingMetrics.ascent, - &aBoundingMetrics.descent, - &aBoundingMetrics.width); -} -#endif - - - -nsresult -nsFreeTypeFont::doGetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength, - PRInt32* aLeftBearing, - PRInt32* aRightBearing, - PRInt32* aAscent, - PRInt32* aDescent, - PRInt32* aWidth) -{ - nsresult rv; - - *aLeftBearing = 0; - *aRightBearing = 0; - *aAscent = 0; - *aDescent = 0; - *aWidth = 0; - - if (aLength < 1) { - return NS_ERROR_FAILURE; - } - - FT_Pos pos = 0; - FT_BBox bbox; - // initialize to "uninitialized" values - bbox.xMin = bbox.yMin = 32000; - bbox.xMax = bbox.yMax = -32000; - - // get the face/size from the FreeType cache - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return NS_ERROR_FAILURE; - - FTC_Image_Cache icache; - mFt2->GetImageCache(&icache); - if (!icache) - return NS_ERROR_FAILURE; - - // get the text size - PRUint32 i, extraSurrogateLength; - for (i=0; iGetCharIndex(face, code_point, &glyph_index); - - //NS_ASSERTION(glyph_index,"failed to get glyph"); - if (glyph_index) { - rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph); - NS_ASSERTION(NS_SUCCEEDED(rv),"error loading glyph"); - } - if ((glyph_index) && (NS_SUCCEEDED(rv))) { - mFt2->GlyphGetCBox(glyph, ft_glyph_bbox_pixels, &glyph_bbox); - advance = FT_16_16_TO_REG(glyph->advance.x); - } - else { - // allocate space to draw an empty box in - GetFallbackGlyphMetrics(&glyph_bbox, face); - advance = glyph_bbox.xMax + 1; - } - bbox.xMin = PR_MIN(pos+glyph_bbox.xMin, bbox.xMin); - bbox.xMax = PR_MAX(pos+glyph_bbox.xMax, bbox.xMax); - bbox.yMin = PR_MIN(glyph_bbox.yMin, bbox.yMin); - bbox.yMax = PR_MAX(glyph_bbox.yMax, bbox.yMax); - pos += advance; - } - - // check we got at least one size - if (bbox.xMin > bbox.xMax) - bbox.xMin = bbox.xMax = bbox.yMin = bbox.yMax = 0; - - *aLeftBearing = bbox.xMin; - *aRightBearing = bbox.xMax; - *aAscent = bbox.yMax; - *aDescent = -bbox.yMin; - *aWidth = pos; - return NS_OK; -} - -GdkFont* -nsFreeTypeFont::GetGDKFont() -{ - return nsnull; -} - -PRBool -nsFreeTypeFont::GetGDKFontIs10646() -{ - return PR_TRUE; -} - -PRBool -nsFreeTypeFont::IsFreeTypeFont() -{ - return PR_TRUE; -} - -gint -nsFreeTypeFont::GetWidth(const PRUnichar* aString, PRUint32 aLength) -{ - FT_UInt glyph_index; - FT_Glyph glyph; - FT_Pos origin_x = 0; - - // get the face/size from the FreeType cache - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return 0; - - FTC_Image_Cache icache; - mFt2->GetImageCache(&icache); - if (!icache) - return 0; - - PRUint32 i, extraSurrogateLength; - for (i=0; iGetCharIndex((FT_Face)face, code_point, &glyph_index); - nsresult rv; - rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph); - NS_ASSERTION(NS_SUCCEEDED(rv),"error loading glyph"); - if (NS_FAILED(rv)) { - origin_x += face->size->metrics.x_ppem/2 + 2; - continue; - } - origin_x += FT_16_16_TO_REG(glyph->advance.x); - } - - return origin_x; -} - -gint -nsFreeTypeFont::DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength) -{ - NS_ERROR("should never call nsFreeTypeFont::DrawString"); - return 0; -} - -PRUint32 -nsFreeTypeFont::Convert(const PRUnichar* aSrc, PRUint32 aSrcLen, - PRUnichar* aDest, PRUint32 aDestLen) -{ - NS_ERROR("should not be calling nsFreeTypeFont::Convert"); - return 0; -} - -int -nsFreeTypeFont::ascent() -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return 0; - return FT_DESIGN_UNITS_TO_PIXELS(face->ascender, face->size->metrics.y_scale); -} - -int -nsFreeTypeFont::descent() -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return 0; - return FT_DESIGN_UNITS_TO_PIXELS(-face->descender, face->size->metrics.y_scale); -} - -int -nsFreeTypeFont::max_ascent() -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return 0; - - TT_OS2 * tt_os2; - mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); - NS_ASSERTION(tt_os2, "unable to get OS2 table"); - if (tt_os2) - return FT_DESIGN_UNITS_TO_PIXELS(tt_os2->sTypoAscender, - face->size->metrics.y_scale); - else - return FT_DESIGN_UNITS_TO_PIXELS(face->bbox.yMax, - face->size->metrics.y_scale); -} - -int -nsFreeTypeFont::max_descent() -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return 0; - - TT_OS2 *tt_os2; - mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); - NS_ASSERTION(tt_os2, "unable to get OS2 table"); - if (tt_os2) - return FT_DESIGN_UNITS_TO_PIXELS(-tt_os2->sTypoDescender, - face->size->metrics.y_scale); - else - return FT_DESIGN_UNITS_TO_PIXELS(-face->bbox.yMin, - face->size->metrics.y_scale); -} - -int -nsFreeTypeFont::max_width() -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return 0; - return FT_DESIGN_UNITS_TO_PIXELS(face->max_advance_width, - face->size->metrics.x_scale); -} - -PRBool -nsFreeTypeFont::getXHeight(unsigned long &val) -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face || !val) - return PR_FALSE; - val = FT_DESIGN_UNITS_TO_PIXELS(face->height, face->size->metrics.y_scale); - - return PR_TRUE; -} - -PRBool -nsFreeTypeFont::underlinePosition(long &val) -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return PR_FALSE; - val = FT_DESIGN_UNITS_TO_PIXELS(-face->underline_position, - face->size->metrics.y_scale); - return PR_TRUE; -} - -PRBool -nsFreeTypeFont::underline_thickness(unsigned long &val) -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return PR_FALSE; - val = FT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness, - face->size->metrics.y_scale); - return PR_TRUE; -} - -PRBool -nsFreeTypeFont::superscript_y(long &val) -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return PR_FALSE; - - TT_OS2 *tt_os2; - mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); - NS_ASSERTION(tt_os2, "unable to get OS2 table"); - if (!tt_os2) - return PR_FALSE; - - val = FT_DESIGN_UNITS_TO_PIXELS(tt_os2->ySuperscriptYOffset, - face->size->metrics.y_scale); - return PR_TRUE; -} - -PRBool -nsFreeTypeFont::subscript_y(long &val) -{ - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return PR_FALSE; - - TT_OS2 *tt_os2; - mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); - NS_ASSERTION(tt_os2, "unable to get OS2 table"); - if (!tt_os2) - return PR_FALSE; - - val = FT_DESIGN_UNITS_TO_PIXELS(tt_os2->ySubscriptYOffset, - face->size->metrics.y_scale); - - // some fonts have the sign wrong. it should be always positive. - val = (val < 0) ? -val : val; - return PR_TRUE; -} - -// -// class nsFreeTypeRender -// - -// this needs to be written -class nsFreeTypeRender : nsFreeTypeFont { -private: - nsFreeTypeRender(); -}; - -// -// class nsFreeTypeXImage data/functions -// -nsFreeTypeXImage::nsFreeTypeXImage() -{ - NS_ERROR("should never call nsFreeTypeXImage::nsFreeTypeXImage"); -} - -nsFreeTypeXImage::nsFreeTypeXImage(nsITrueTypeFontCatalogEntry *aFaceID, - PRUint16 aPixelSize, const char *aName) -: nsFreeTypeFont(aFaceID, aPixelSize, aName) -{ - //NS_ERROR("should never call nsFreeTypeXImage::nsFreeTypeXImage"); -} - -gint -nsFreeTypeXImage::DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength) -{ - -#if DEBUG_SHOW_GLYPH_BOX - PRUint32 x, y; - // grey shows image size - // red shows character cells - // green box shows text ink -#endif - - if (aLength < 1) { - return 0; - } - - // get the face/size from the FreeType cache - FT_Face face = getFTFace(); - NS_ASSERTION(face, "failed to get face/size"); - if (!face) - return 0; - - nsresult rslt; - PRInt32 leftBearing, rightBearing, ascent, descent, width; - rslt = doGetBoundingMetrics(aString, aLength, &leftBearing, &rightBearing, - &ascent, &descent, &width); - if (NS_FAILED(rslt)) - return 0; - - // make sure we bring down enough background for blending - rightBearing = PR_MAX(rightBearing, width+1); - - // offset in the ximage to the x origin - PRInt32 x_origin = PR_MAX(0, -leftBearing); - // offset in the ximage to the x origin - PRInt32 y_origin = ascent; - PRInt32 x_pos = x_origin; - - int image_width = x_origin + rightBearing; - int image_height = y_origin + PR_MAX(descent, 0); - if ((image_width<=0) || (image_height<=0)) { - // if we do not have any pixels then no point in trying to draw - // eg: the space char has 0 height - NS_ASSERTION(width>=0, "Negative width"); - return width; - } - Display *dpy = GDK_DISPLAY(); - Drawable win = GDK_WINDOW_XWINDOW(aSurface->GetDrawable()); - GC gc = GDK_GC_XGC(aContext->GetGC()); - XGCValues values; - if (!XGetGCValues(dpy, gc, GCForeground, &values)) { - NS_ERROR("failed to get foreground pixel"); - return 0; - } - nscolor color = nsX11AlphaBlend::PixelToNSColor(values.foreground); - -#if DEBUG_SHOW_GLYPH_BOX - // show X/Y origin - XDrawLine(dpy, win, DefaultGC(dpy, 0), aX-2, aY, aX+2, aY); - XDrawLine(dpy, win, DefaultGC(dpy, 0), aX, aY-2, aX, aY+2); - // show width - XDrawLine(dpy, win, DefaultGC(dpy, 0), aX-x_origin, aY-y_origin-2, - aX+rightBearing, aY-y_origin-2); -#endif - - // - // Get the background - // - XImage *sub_image = nsX11AlphaBlend::GetBackground(dpy, DefaultScreen(dpy), - win, aX-x_origin, aY-y_origin, - image_width, image_height); - if (sub_image==nsnull) { -#ifdef DEBUG - int screen = DefaultScreen(dpy); - // complain if the requested area is not completely off screen - int win_width = DisplayWidth(dpy, screen); - int win_height = DisplayHeight(dpy, screen); - if (((int)(aX-leftBearing+image_width) > 0) // not hidden to left - && ((int)(aX-leftBearing) < win_width) // not hidden to right - && ((int)(aY-ascent+image_height) > 0)// not hidden to top - && ((int)(aY-ascent) < win_height)) // not hidden to bottom - { - NS_ASSERTION(sub_image, "failed to get the image"); - } -#endif - return 0; - } - -#if DEBUG_SHOW_GLYPH_BOX - DEBUG_AADRAWBOX(sub_image,0,0,image_width,image_height,0,0,0,255/4); - nscolor black NS_RGB(0,255,0); - blendPixel blendPixelFunc = nsX11AlphaBlend::GetBlendPixel(); - // x origin - for (x=0; x<(unsigned int)image_height; x++) - if (x%4==0) (*blendPixelFunc)(sub_image, x_origin, x, black, 255/2); - // y origin - for (y=0; y<(unsigned int)image_width; y++) - if (y%4==0) (*blendPixelFunc)(sub_image, y, ascent-1, black, 255/2); -#endif - - FTC_Image_Cache icache; - mFt2->GetImageCache(&icache); - if (!icache) - return 0; - - // - // Get aa glyphs and blend with background - // - blendGlyph blendGlyph = nsX11AlphaBlend::GetBlendGlyph(); - PRUint32 i, extraSurrogateLength; - for (i=0; iGetCharIndex(face, code_point, &glyph_index); - if (glyph_index) { - rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph); - } - if ((glyph_index) && (NS_SUCCEEDED(rv))) { - mFt2->GlyphGetCBox(glyph, ft_glyph_bbox_pixels, &glyph_bbox); - } - else { - // draw an empty box for the missing glyphs - GetFallbackGlyphMetrics(&glyph_bbox, face); - int x, y, w = glyph_bbox.xMax, h = glyph_bbox.yMax; - for (x=1; x=glyph_bbox.yMax,"glyph too tall"); - NS_ASSERTION(x_pos>=-aaglyph.GetLBearing(),"glyph extends too far to left"); - -#if DEBUG_SHOW_GLYPH_BOX - // draw box around part of glyph that extends to the left - // of the main area (negative LBearing) - if (aaglyph.GetLBearing() < 0) { - DEBUG_AADRAWBOX(sub_image, x_pos + aaglyph.GetLBearing(), - ascent-glyph_bbox.yMax, - -aaglyph.GetLBearing(), glyph_bbox.yMax, 255,0,0, 255/4); - } - // draw box around main glyph area - DEBUG_AADRAWBOX(sub_image, x_pos, ascent-glyph_bbox.yMax, - aaglyph.GetAdvance(), glyph_bbox.yMax, 0,255,0, 255/4); - // draw box around part of glyph that extends to the right - // of the main area (negative LBearing) - if (aaglyph.GetRBearing() > (int)aaglyph.GetAdvance()) { - DEBUG_AADRAWBOX(sub_image, x_pos + aaglyph.GetAdvance(), - ascent-glyph_bbox.yMax, - aaglyph.GetRBearing()-aaglyph.GetAdvance(), - glyph_bbox.yMax, 0,0,255, 255/4); - } -#endif - (*blendGlyph)(sub_image, &aaglyph, sLinearWeightTable, color, - x_pos + aaglyph.GetLBearing(), ascent-glyph_bbox.yMax); - - x_pos += aaglyph.GetAdvance(); - } - - // - // Send it to the display - // - XPutImage(dpy, win, gc, sub_image, 0, 0, aX-x_origin , aY-ascent, - image_width, image_height); - XDestroyImage(sub_image); - - return width; -} - -/////////////////////////////////////////////////////////////////////// -// -// class nsFreeTypeXImage data/functions -// -/////////////////////////////////////////////////////////////////////// - -nsFreeTypeXImageSBC::nsFreeTypeXImageSBC() -{ - NS_ERROR("should never call nsFreeTypeXImageSBC::nsFreeTypeXImageSBC"); -} - -nsFreeTypeXImageSBC::nsFreeTypeXImageSBC(nsITrueTypeFontCatalogEntry *aFaceID, - PRUint16 aPixelSize, - const char *aName) -: nsFreeTypeXImage(aFaceID, aPixelSize, aName) -{ -} - -#ifdef MOZ_MATHML -nsresult -nsFreeTypeXImageSBC::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - nsresult res; - char buf[512]; - PRInt32 bufLen = sizeof(buf); - PRInt32 stringLen = aLength; - nsCAutoString familyName; - mFaceID->GetFamilyName(familyName); - nsTTFontFamilyEncoderInfo *ffei = - nsFreeType2::GetCustomEncoderInfo(familyName.get()); - NS_ASSERTION(ffei,"failed to find font encoder info"); - if (!ffei) - return NS_ERROR_FAILURE; - res = ffei->mEncodingInfo->mConverter->Convert(aString, &stringLen, - buf, &bufLen); - NS_ASSERTION((aLength&&bufLen)||(!aLength&&!bufLen), "converter failed"); - - // - // Widen to 16 bit - // - PRUnichar unibuf[512]; - int i; - for (i=0; iGetFamilyName(familyName); - nsTTFontFamilyEncoderInfo *ffei = - nsFreeType2::GetCustomEncoderInfo(familyName.get()); - NS_ASSERTION(ffei,"failed to find font encoder info"); - if (!ffei) - return 0; - ffei->mEncodingInfo->mConverter->Convert(aString, &stringLen, - buf, &bufLen); - NS_ASSERTION((aLength&&bufLen)||(!aLength&&!bufLen), "converter failed"); - - // - // Widen to 16 bit - // - PRUnichar unibuf[512]; - int i; - for (i=0; iGetFamilyName(familyName); - nsTTFontFamilyEncoderInfo *ffei = - nsFreeType2::GetCustomEncoderInfo(familyName.get()); - NS_ASSERTION(ffei,"failed to find font encoder info"); - if (!ffei) - return 0; - ffei->mEncodingInfo->mConverter->Convert(aString, &stringLen, - buf, &bufLen); - NS_ASSERTION((aLength&&bufLen)||(!aLength&&!bufLen), "converter failed"); - - // - // Widen to 16 bit - // - PRUnichar unibuf[512]; - int i; - for (i=0; ixMin = 0; - aBoundingBox->yMin = 0; - aBoundingBox->xMax = PR_MAX(aFace->size->metrics.x_ppem/2 - 1, 0); - aBoundingBox->yMax = PR_MAX(aFace->size->metrics.y_ppem/2, 1); -} - -void -WeightTableInitCorrection(PRUint8* aTable, PRUint8 aMinValue, - double aGain) -{ - // setup the wieghting table - for (int i=0; i<256; i++) { - int val = i + (int)rint((double)(i-aMinValue)*aGain); - val = PR_MAX(0, val); - val = PR_MIN(val, 255); - aTable[i] = (PRUint8)val; - } -} - -#endif - diff --git a/gfx/src/x11shared/nsFontFreeType.h b/gfx/src/x11shared/nsFontFreeType.h deleted file mode 100644 index e47307710134..000000000000 --- a/gfx/src/x11shared/nsFontFreeType.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * Louie Zhao - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef nsFontFreeType_h__ -#define nsFontFreeType_h__ - -#include "gfx-config.h" -#include "nsFontMetricsGTK.h" -#include "nsFreeType.h" - -#if (!defined(MOZ_ENABLE_FREETYPE2)) -class nsFreeTypeFont : public nsFontGTK { -public: - static nsFreeTypeFont *NewFont(nsITrueTypeFontCatalogEntry*, - PRUint16, const char *); -}; -#else - -class nsFreeTypeFont : public nsFontGTK -{ -public: - - nsFreeTypeFont(); - nsFreeTypeFont(nsITrueTypeFontCatalogEntry *, PRUint16, const char *); - virtual ~nsFreeTypeFont(void); - static nsFreeTypeFont *NewFont(nsITrueTypeFontCatalogEntry*, - PRUint16, const char *); - - void LoadFont(void); - - virtual GdkFont* GetGDKFont(void); - virtual PRBool GetGDKFontIs10646(void); - virtual PRBool IsFreeTypeFont(void); - - virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength); - virtual gint DrawString(nsRenderingContextGTK* aContext, - nsDrawingSurfaceGTK* aSurface, nscoord aX, - nscoord aY, const PRUnichar* aString, - PRUint32 aLength); -#ifdef MOZ_MATHML - virtual nsresult GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); -#endif - virtual nsresult doGetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - PRInt32* aLeftBearing, - PRInt32* aRightBearing, - PRInt32* aAscent, - PRInt32* aDescent, - PRInt32* aWidth); - - virtual PRUint32 Convert(const PRUnichar* aSrc, PRUint32 aSrcLen, - PRUnichar* aDest, PRUint32 aDestLen); - - FT_Face getFTFace(); - int ascent(); - int descent(); - PRBool getXHeight(unsigned long &val); - int max_ascent(); - int max_descent(); - int max_width(); - PRBool superscript_y(long &val); - PRBool subscript_y(long &val); - PRBool underlinePosition(long &val); - PRBool underline_thickness(unsigned long &val); - - FT_Error FaceRequester(FT_Face* aface); - static void FreeGlobals(); - - static PRUint8 sLinearWeightTable[256]; - -protected: - XImage *GetXImage(PRUint32 width, PRUint32 height); - nsITrueTypeFontCatalogEntry *mFaceID; - PRUint16 mPixelSize; - FTC_Image_Desc mImageDesc; - nsCOMPtr mFt2; -}; - -void WeightTableInitCorrection(PRUint8*, PRUint8, double); - -#endif -#endif - diff --git a/gfx/src/x11shared/nsNameValuePairDB.cpp b/gfx/src/x11shared/nsNameValuePairDB.cpp deleted file mode 100644 index 0767379ee2da..000000000000 --- a/gfx/src/x11shared/nsNameValuePairDB.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nspr.h" -#include "nsCOMPtr.h" -#include "nsAppDirectoryServiceDefs.h" -#include "nsNameValuePairDB.h" -#include "nsILocalFile.h" - -#define NVPDB_VERSION_MAJOR 1 -#define NVPDB_VERSION_MINOR 0 -#define NVPDB_VERSION_MAINTENANCE 0 - -#ifdef DEBUG -# define NVPDB_PRINTF(x) \ - PR_BEGIN_MACRO \ - printf x ; \ - printf(", %s %d\n", __FILE__, __LINE__); \ - PR_END_MACRO -#else -# define NVPDB_PRINTF(x) -#endif - -PRBool -nsNameValuePairDB::CheckHeader() -{ - const char *name, *value; - int num, major, minor, maintenance; - PRBool foundVersion = PR_FALSE; - - if (!mFile) - return PR_FALSE; - - if (fseek(mFile, 0L, SEEK_SET) != 0) - return PR_FALSE; - mCurrentGroup = 0; - mAtEndOfGroup = PR_FALSE; - while (GetNextElement(&name, &value) > 0) { - if (*name == '\0') // ignore comments - continue; - if (strcmp(name, "Version")==0) { - foundVersion = PR_TRUE; - num = sscanf(value, "%d.%d.%d", &major, &minor, &maintenance); - if (num != 3) { - NVPDB_PRINTF(("failed to parse version number (%s)", value)); - return PR_FALSE; - } - - // NVPDB_VERSION_MAJOR - // It is presumed that major versions are not backwards compatibile. - if (major != NVPDB_VERSION_MAJOR) { - NVPDB_PRINTF(("version major %d != %d", major, NVPDB_VERSION_MAJOR)); - return PR_FALSE; - } - - // NVPDB_VERSION_MINOR - // It is presumed that minor versions are backwards compatible - // but will have additional features. - // Put any tests related to minor versions here. - - // NVPDB_VERSION_MAINTENANCE - // It is presumed that maintenance versions are backwards compatible, - // have no new features, but can have bug fixes. - // Put any tests related to maintenance versions here. - - mMajorNum = major; - mMinorNum = minor; - mMaintenanceNum = maintenance; - } - } - - return foundVersion; -} - -// -// Re-get an element. Used if the element is bigger than -// the buffer that was first passed in -// -// PRInt32 GetCurrentElement(const char** aName, const char** aValue, -// char *aBuffer, PRUint32 aBufferLen); -// -// to implement this the GetNextElement methods need to save -// the file position so this routine can seek backward to it. -// - -PRInt32 -nsNameValuePairDB::GetNextElement(const char** aName, const char** aValue) -{ - return GetNextElement(aName, aValue, mBuf, sizeof(mBuf)); -} - -// -// Get the next element -// -// returns 1 if complete element read -// return 0 on end of file -// returns a negative number on error -// if error < -NVPDB_MIN_BUFLEN -// then the value is the negative of the needed buffer len -// -// -PRInt32 -nsNameValuePairDB::GetNextElement(const char** aName, const char** aValue, - char *aBuffer, PRUint32 aBufferLen) -{ - char *line, *name, *value; - unsigned int num; - int len; - unsigned int groupNum; - - *aName = ""; - *aValue = ""; - - if (aBufferLen < NVPDB_MIN_BUFLEN) { - return NVPDB_BUFFER_TOO_SMALL; - } - - if (mAtEndOfGroup) { - return NVPDB_END_OF_GROUP; - } - - // - // Get a line - // - line = fgets(aBuffer, aBufferLen, mFile); - if (!line) { - if (feof(mFile)) { // end of file - mAtEndOfGroup = PR_TRUE; - mAtEndOfCatalog = PR_TRUE; - return NVPDB_END_OF_FILE; - } - return NVPDB_FILE_IO_ERROR; - } - - // - // Check we got a complete line - // - len = strlen(line); - NS_ASSERTION(len!=0, "an empty string is invalid"); - if (len == 0) - return NVPDB_GARBLED_LINE; - if (line[len-1] != '\n') { - len++; // space for the line terminator - while (1) { - int val = getc(mFile); - if (val == EOF) - return -len; - len++; - if (val == '\n') - return -len; - } - } - len--; - line[len] = '\0'; - //NVPDB_PRINTF(("line = (%s)", line)); - - // - // Check the group number - // - num = sscanf(line, "%u", &groupNum); - if ((num != 1) || (groupNum != (unsigned)mCurrentGroup)) - return NVPDB_END_OF_GROUP; - - // - // Get the name - // - name = strchr(line, ' '); - if ((!name) || (name[1]=='\0')) - return NVPDB_GARBLED_LINE; - name++; - - // - // If it is a comment - // return a blank name (strlen(*aName)==0) - // return the comment in the value field - // - if (*name == '#') { - *aValue = name; - return 1; - } - - // - // Get the value - // - value = strchr(name, '='); - if (!value) - return NVPDB_GARBLED_LINE; - *value = '\0'; - value++; - - // - // Check for end of group - // - if (strcmp(name,"end")==0) { - mAtEndOfGroup = PR_TRUE; - return NVPDB_END_OF_GROUP; - } - - // - // Got the name and value - // - *aName = name; - *aValue = value; - return 1; -} - -PRBool -nsNameValuePairDB::GetNextGroup(const char** aType) -{ - return GetNextGroup(aType, nsnull, 0); -} - -PRBool -nsNameValuePairDB::GetNextGroup(const char** aType, const char* aName) -{ - return GetNextGroup(aType, aName, strlen(aName)); -} - -PRBool -nsNameValuePairDB::GetNextGroup(const char** aType, const char* aName, int aLen) -{ - const char *name, *value; - long pos = 0; - - *aType = ""; - - if (mAtEndOfCatalog) - return PR_FALSE; - - // - // Move to end of current Group - // - while (GetNextElement(&name, &value) > 0) - continue; - mCurrentGroup++; - mAtEndOfGroup = PR_FALSE; - // save current pos in case this in not the desired type - // and we need to backup - if (aName) - pos = ftell(mFile); - - // check if there are more Groups - if (GetNextElement(&name, &value) <= 0) { - mAtEndOfGroup = PR_TRUE; - mAtEndOfCatalog = PR_TRUE; - return PR_FALSE; - } - if (strcmp(name,"begin")) - goto GetNext_Error; - - // check if this is the desired type - if (aName) { - if (strncmp(value,aName,aLen)) { - fseek(mFile, pos, SEEK_SET); - mCurrentGroup--; - mAtEndOfGroup = PR_TRUE; - return PR_FALSE; - } - } - - *aType = value; - return PR_TRUE; - -GetNext_Error: - mError = PR_TRUE; - NVPDB_PRINTF(("GetNext_Error")); - return PR_FALSE; -} - -nsNameValuePairDB::nsNameValuePairDB() -{ - mFile = nsnull; - mBuf[0] = '\0'; - mMajorNum = 0; - mMinorNum = 0; - mMaintenanceNum = 0; - mCurrentGroup = 0; - mAtEndOfGroup = PR_FALSE; - mAtEndOfCatalog = PR_FALSE; - mError = PR_FALSE; -} - -nsNameValuePairDB::~nsNameValuePairDB() -{ - if (mFile) { - fclose(mFile); - mFile = nsnull; - } -} - -PRBool -nsNameValuePairDB::OpenForRead(const nsACString & aCatalogName) // native charset -{ - nsresult result; - - nsCOMPtr local_file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, - &result); - if (NS_FAILED(result)) - goto error_return; - - local_file->InitWithNativePath(aCatalogName); - local_file->OpenANSIFileDesc("r", &mFile); - if (mFile && CheckHeader()) - return PR_TRUE; - -error_return: - mError = PR_TRUE; - NVPDB_PRINTF(("OpenForRead error")); - return PR_FALSE; -} - -PRBool -nsNameValuePairDB::OpenTmpForWrite(const nsACString& aCatalogName) // native charset -{ - nsresult result; - nsCOMPtr local_file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, - &result); - if (NS_FAILED(result)) - return PR_FALSE; - local_file->InitWithNativePath(aCatalogName + NS_LITERAL_CSTRING(".tmp")); - local_file->OpenANSIFileDesc("w+", &mFile); - if (mFile == nsnull) - return PR_FALSE; - - // Write the header - mAtEndOfGroup = PR_TRUE; - mCurrentGroup = -1; - PutStartGroup("Header"); - char buf[64]; - PutElement("", "########################################"); - PutElement("", "# #"); - PutElement("", "# Name Value Pair DB #"); - PutElement("", "# #"); - PutElement("", "# This is a program generated file #"); - PutElement("", "# #"); - PutElement("", "# Do not edit #"); - PutElement("", "# #"); - PutElement("", "########################################"); - PR_snprintf(buf, sizeof(buf), "%d.%d.%d", NVPDB_VERSION_MAJOR, - NVPDB_VERSION_MINOR, NVPDB_VERSION_MAINTENANCE); - PutElement("Version", buf); - PutEndGroup("Header"); - - return PR_TRUE; -} - -PRBool -nsNameValuePairDB::PutElement(const char* aName, const char* aValue) -{ - if (mAtEndOfGroup) { - mError = PR_TRUE; - NVPDB_PRINTF(("PutElement_Error")); - return PR_FALSE; - } - - if ((!*aName) && (*aValue == '#')) - fprintf(mFile, "%u %s\n", mCurrentGroup, aValue); - else - fprintf(mFile, "%u %s=%s\n", mCurrentGroup, aName, aValue); -#ifdef DEBUG - fflush(mFile); -#endif - return PR_TRUE; -} - -PRBool -nsNameValuePairDB::PutEndGroup(const char* aType) -{ - if (mAtEndOfGroup) { - mError = PR_TRUE; - NVPDB_PRINTF(("PutEndGroup_Error")); - return PR_FALSE; - } - - mAtEndOfGroup = PR_TRUE; - fprintf(mFile, "%u end=%s\n", mCurrentGroup, aType); -#ifdef DEBUG - fflush(mFile); -#endif - return PR_TRUE; -} - -PRBool -nsNameValuePairDB::PutStartGroup(const char* aType) -{ - if (!mAtEndOfGroup) { - mError = PR_TRUE; - NVPDB_PRINTF(("PutStartGroup_Error")); -#ifdef DEBUG - fflush(mFile); -#endif - return PR_FALSE; - } - - mAtEndOfGroup = PR_FALSE; - mCurrentGroup++; - fprintf(mFile, "%u begin=%s\n", mCurrentGroup, aType); -#ifdef DEBUG - fflush(mFile); -#endif - return PR_TRUE; -} - -PRBool -nsNameValuePairDB::RenameTmp(const char* aCatalogName) -{ - nsresult rv; - nsCOMPtr dir; - PRBool exists = PR_FALSE; - nsCAutoString old_name(aCatalogName); - nsDependentCString current_name(aCatalogName); - nsCAutoString tmp_name(aCatalogName); - nsCAutoString old_name_tail; - nsCAutoString current_name_tail; - nsCOMPtr old_file; - nsCOMPtr current_file; - nsCOMPtr tmp_file; - nsCAutoString parent_dir; - nsCAutoString parent_path; - nsCAutoString cur_path; - - // - // Split the parent dir and file name - // - PRInt32 slash = 0, last_slash = -1; - nsCAutoString fontDirName(aCatalogName); - // RFindChar not coded so do it by hand - while ((slash=fontDirName.FindChar('/', slash))>=0) { - last_slash = slash; - slash++; - } - if (last_slash < 0) - goto Rename_Error; - - fontDirName.Left(parent_dir, last_slash); - dir = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - goto Rename_Error; - dir->InitWithNativePath(parent_dir); - dir->GetNativePath(parent_path); - - if (!mAtEndOfGroup || mError) - goto Rename_Error; - - // - // check that we have a tmp copy - // - tmp_name.Append(".tmp"); - tmp_file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - goto Rename_Error; - tmp_file->InitWithNativePath(tmp_name); - tmp_file->Exists(&exists); - if (!exists) - goto Rename_Error; - - // - // get rid of any old copy - // - old_name.Append(".old"); - old_file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - goto Rename_Error; - old_file->InitWithNativePath(old_name); - - // - // Check we have a current copy - // - current_file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - goto Rename_Error; - current_file->InitWithNativePath(current_name); - current_file->Exists(&exists); - if (exists) { - // - // Rename the current copy to old - // - current_file->GetNativePath(cur_path); - old_name.Right(old_name_tail, old_name.Length() - last_slash - 1); - rv = current_file->MoveToNative(dir, old_name_tail); - if (NS_FAILED(rv)) - goto Rename_Error; - } - - // - // Rename the tmp to current - // - current_name_tail = Substring(current_name, last_slash+1, - current_name.Length() - (last_slash + 1)); - rv = tmp_file->MoveToNative(dir, current_name_tail); - if (NS_FAILED(rv)) - goto Rename_Error; - - // - // remove the previous copy - // - if (exists) { - old_file->Remove(PR_FALSE); - } - - return PR_TRUE; - -Rename_Error: - mError = PR_TRUE; - NVPDB_PRINTF(("Rename_Error")); - return PR_FALSE; -} - diff --git a/gfx/src/x11shared/nsNameValuePairDB.h b/gfx/src/x11shared/nsNameValuePairDB.h deleted file mode 100644 index 98a24c4ff12d..000000000000 --- a/gfx/src/x11shared/nsNameValuePairDB.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef NSNAMEVALUEPAIRDB_H -#define NSNAMEVALUEPAIRDB_H - -#include "nsString.h" - -#define FC_BUF_LEN 1024 - -#define NVPDB_MIN_BUFLEN 100 - -// -// Errors -// -#define NVPDB_END_OF_FILE 0 -#define NVPDB_BUFFER_TOO_SMALL -1 -#define NVPDB_END_OF_GROUP -2 -#define NVPDB_FILE_IO_ERROR -3 -#define NVPDB_GARBLED_LINE -4 - -class nsNameValuePairDB { -public: - nsNameValuePairDB(); - ~nsNameValuePairDB(); - - inline PRBool HadError() { return mError; }; - // implement this to re-read an element if it is larger than the buffer - // PRInt32 GetCurrentElement(const char** aName, const char** aValue, - // char *aBuffer, PRUint32 aBufferLen); - PRBool GetNextGroup(const char** aType); - PRBool GetNextGroup(const char** aType, const char* aName); - PRBool GetNextGroup(const char** aType, const char* aName, int aLen); - PRInt32 GetNextElement(const char** aName, const char** aValue); - PRInt32 GetNextElement(const char** aName, const char** aValue, - char *aBuffer, PRUint32 aBufferLen); - PRBool OpenForRead(const nsACString& aCatalogName); // native charset - PRBool OpenTmpForWrite(const nsACString& aCatalogName); // native charset - PRBool PutElement(const char* aName, const char* aValue); - PRBool PutEndGroup(const char* aType); - PRBool PutStartGroup(const char* aType); - PRBool RenameTmp(const char* aCatalogName); - -protected: - PRBool CheckHeader(); - PRUint16 mMajorNum; - PRUint16 mMinorNum; - PRUint16 mMaintenanceNum; - FILE* mFile; - char mBuf[FC_BUF_LEN]; - PRInt32 mCurrentGroup; - PRPackedBool mAtEndOfGroup; - PRPackedBool mAtEndOfCatalog; - PRPackedBool mError; -private: -}; - -#endif /* NSNAMEVALUEPAIRDB_H */ - diff --git a/gfx/src/x11shared/nsX11AlphaBlend.cpp b/gfx/src/x11shared/nsX11AlphaBlend.cpp deleted file mode 100644 index a5a42d096c67..000000000000 --- a/gfx/src/x11shared/nsX11AlphaBlend.cpp +++ /dev/null @@ -1,1169 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: - * - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include -#include "gfx-config.h" -#include "nsCRT.h" -#include "nspr.h" -#include "nsAntiAliasedGlyph.h" -#include "nsX11AlphaBlend.h" - -#define ENABLE_X11ALPHA_BLEND_PRINTF 1 - -#if ENABLE_X11ALPHA_BLEND_PRINTF -static PRUint32 gX11AlphaBlendDebug; -# include -#define NS_X11_ALPHA_BLEND_DEBUG 0x01 - -#define DEBUG_PRINTF_MACRO(x, type) \ - PR_BEGIN_MACRO \ - if (gX11AlphaBlendDebug & (type)) { \ - printf x ; \ - printf(", %s %d\n", __FILE__, __LINE__); \ - } \ - PR_END_MACRO - -#else /* ENABLE_X11ALPHA_BLEND_PRINTF */ - -#define DEBUG_PRINTF_MACRO(x, type) \ - PR_BEGIN_MACRO \ - PR_END_MACRO - -#endif /* ENABLE_X11ALPHA_BLEND_PRINTF */ - -#define X11ALPHA_BLEND_PRINTF(x) \ - DEBUG_PRINTF_MACRO(x, NS_X11_ALPHA_BLEND_DEBUG) - -static void dummy_BlendPixel(XImage *, int x, int y, nscolor color, int a); -#ifdef DEBUG -static void nsBlendPixel555 (XImage *, int x, int y, nscolor color, int a); -static void nsBlendPixel555_br(XImage *, int x, int y, nscolor color, int a); -static void nsBlendPixel565 (XImage *, int x, int y, nscolor color, int a); -static void nsBlendPixel565_br(XImage *, int x, int y, nscolor color, int a); -static void nsBlendPixel888_lsb(XImage *, int x, int y, nscolor color, int a); -static void nsBlendPixel888_msb(XImage *, int x, int y, nscolor color, int a); -static void nsBlendPixel0888 (XImage *, int x, int y, nscolor color, int a); -static void nsBlendPixel0888_br(XImage *, int x, int y, nscolor color, int a); -#else -# define nsBlendPixel555 dummy_BlendPixel -# define nsBlendPixel555_br dummy_BlendPixel -# define nsBlendPixel565 dummy_BlendPixel -# define nsBlendPixel565_br dummy_BlendPixel -# define nsBlendPixel888_lsb dummy_BlendPixel -# define nsBlendPixel888_msb dummy_BlendPixel -# define nsBlendPixel0888 dummy_BlendPixel -# define nsBlendPixel0888_br dummy_BlendPixel -#endif - -static void nsBlendMonoImage555 (XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static void nsBlendMonoImage555_br(XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static void nsBlendMonoImage565 (XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static void nsBlendMonoImage565_br(XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static void nsBlendMonoImage888_lsb(XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static void nsBlendMonoImage888_msb(XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static void nsBlendMonoImage0888(XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static void nsBlendMonoImage0888_br(XImage*,nsAntiAliasedGlyph*, - PRUint8*, nscolor, int, int); -static nscolor nsPixelToNscolor555 (unsigned long aPixel); -static nscolor nsPixelToNscolor565 (unsigned long aPixel); -static nscolor nsPixelToNscolor888_lsb(unsigned long aPixel); -static nscolor nsPixelToNscolor888_msb(unsigned long aPixel); - -static void dummy_BlendMonoImage(XImage *, nsAntiAliasedGlyph *, PRUint8*, - nscolor, int, int); -static nscolor dummy_PixelToNSColor(unsigned long); - -// sPixelToNSColor -// -// X11AlphaBlend Globals -// -PRBool nsX11AlphaBlend::sAvailable; -PRUint16 nsX11AlphaBlend::sBitmapPad; -PRUint16 nsX11AlphaBlend::sBitsPerPixel; -blendGlyph nsX11AlphaBlend::sBlendMonoImage; -blendPixel nsX11AlphaBlend::sBlendPixel; -PRUint16 nsX11AlphaBlend::sBytesPerPixel; -int nsX11AlphaBlend::sDepth; -PRBool nsX11AlphaBlend::sInited; -pixelToNSColor nsX11AlphaBlend::sPixelToNSColor; - -void -nsX11AlphaBlend::ClearGlobals() -{ - sAvailable = PR_FALSE; - sBitmapPad = 0; - sBitsPerPixel = 0; - sBlendMonoImage = dummy_BlendMonoImage; - sBlendPixel = dummy_BlendPixel; - sBytesPerPixel = 1; - sDepth = 0; - sInited = PR_FALSE; - sPixelToNSColor = dummy_PixelToNSColor; -} - -void -nsX11AlphaBlendFreeGlobals() -{ - nsX11AlphaBlend::FreeGlobals(); -} - -void -nsX11AlphaBlend::FreeGlobals() -{ - ClearGlobals(); -} - -nsresult -nsX11AlphaBlendInitGlobals(Display *aDisplay) -{ - X11ALPHA_BLEND_PRINTF(("initialize X11AlphaBlend")); - - nsresult rv = nsX11AlphaBlend::InitGlobals(aDisplay); - - return rv; -} - -nsresult -nsX11AlphaBlend::InitGlobals(Display *aDisplay) -{ - NS_ASSERTION(sInited==PR_FALSE, "InitGlobals called more than once"); - // set all the globals to default values -#if ENABLE_X11ALPHA_BLEND_PRINTF - char* debug = PR_GetEnv("NS_ALPHA_BLEND_DEBUG"); - if (debug) { - PR_sscanf(debug, "%lX", &gX11AlphaBlendDebug); - } -#endif - - ClearGlobals(); - if (!InitLibrary(aDisplay)) - return NS_ERROR_NOT_AVAILABLE; - - return NS_OK; -} - -PRBool -nsX11AlphaBlend::InitLibrary(Display *aDisplay) -{ - if (sInited) - return sAvailable; - - sInited = PR_TRUE; - - Visual *visual = DefaultVisual(aDisplay,DefaultScreen(aDisplay)); - if (visual->c_class != TrueColor) { - X11ALPHA_BLEND_PRINTF(("unsuppored visual class %d", visual->c_class)); - return PR_FALSE; - } - - // - // Get an XImage to get the image information - // - Window root_win = RootWindow(aDisplay, DefaultScreen(aDisplay)); - XImage *img = XGetImage(aDisplay, root_win, 0, 0, 1, 1, 0xffffffff, ZPixmap); - NS_ASSERTION(img, "InitGlobals: XGetImage failed"); - if (!img) - return PR_FALSE; - int byte_order = img->byte_order; - sBitmapPad = img->bitmap_pad; - sBitsPerPixel = img->bits_per_pixel; - sDepth = img->depth; - int blue_mask = img->blue_mask; - int green_mask = img->green_mask; - int red_mask = img->red_mask; - XDestroyImage(img); - - PRBool same_byte_order; -#ifdef IS_LITTLE_ENDIAN - X11ALPHA_BLEND_PRINTF(("endian = little")); - same_byte_order = (byte_order == LSBFirst); -#elif IS_BIG_ENDIAN - X11ALPHA_BLEND_PRINTF(("endian = big")); - same_byte_order = (byte_order == MSBFirst); -#else -# error neither IS_LITTLE_ENDIAN or IS_BIG_ENDIAN is defined -#endif - - X11ALPHA_BLEND_PRINTF(("byte_order = %s", byte_order?"MSB":"LSB")); - X11ALPHA_BLEND_PRINTF(("same_byte_order = %d", same_byte_order)); - - X11ALPHA_BLEND_PRINTF(("sBitmapPad = %d", sBitmapPad)); - X11ALPHA_BLEND_PRINTF(("sDepth = %d", sDepth)); - X11ALPHA_BLEND_PRINTF(("sBitsPerPixel = %d", sBitsPerPixel)); - - if (sBitsPerPixel <= 16) - sBytesPerPixel = 2; - else if (sBitsPerPixel <= 32) - sBytesPerPixel = 4; - else { - X11ALPHA_BLEND_PRINTF(("sBitsPerPixel %d: not supported", sBitsPerPixel)); - return PR_FALSE; - } - X11ALPHA_BLEND_PRINTF(("sBytesPerPixel = %d", sBytesPerPixel)); - - if (sBitsPerPixel==16) { - if ((red_mask==0x7C00) && (green_mask==0x3E0) && (blue_mask==0x1F)) { - // 555 - sAvailable = PR_TRUE; - if (same_byte_order) { - sPixelToNSColor = &nsPixelToNscolor555; - sBlendPixel = &nsBlendPixel555; - sBlendMonoImage = &nsBlendMonoImage555; - } - else { - sPixelToNSColor = &nsPixelToNscolor555; - sBlendPixel = &nsBlendPixel555_br; - sBlendMonoImage = &nsBlendMonoImage555_br; - } - } - else if ((red_mask==0xF800) && (green_mask==0x7E0) && (blue_mask==0x1F)) { - // 565 - sAvailable = PR_TRUE; - if (same_byte_order) { - sPixelToNSColor = &nsPixelToNscolor565; - sBlendPixel = &nsBlendPixel565; - sBlendMonoImage = &nsBlendMonoImage565; - } - else { - sPixelToNSColor = &nsPixelToNscolor565; - sBlendPixel = &nsBlendPixel565_br; - sBlendMonoImage = &nsBlendMonoImage565_br; - } - } - } - else if (sBitsPerPixel==24) { - if ((red_mask==0xFF0000) && (green_mask==0xFF00) && (blue_mask==0xFF)) { - // 888 - sAvailable = PR_TRUE; - if (same_byte_order) { - sPixelToNSColor = &nsPixelToNscolor888_lsb; - sBlendPixel = &nsBlendPixel888_lsb; - sBlendMonoImage = &nsBlendMonoImage888_lsb; - } - else { - sPixelToNSColor = &nsPixelToNscolor888_msb; - sBlendPixel = &nsBlendPixel888_msb; - sBlendMonoImage = &nsBlendMonoImage888_msb; - } - } - } - else if (sBitsPerPixel==32) { - // 0888 - sAvailable = PR_TRUE; - if (same_byte_order) { - sPixelToNSColor = &nsPixelToNscolor888_lsb; - sBlendPixel = &nsBlendPixel0888; - sBlendMonoImage = &nsBlendMonoImage0888; - } - else { - sPixelToNSColor = &nsPixelToNscolor888_lsb; - sBlendPixel = &nsBlendPixel0888_br; - sBlendMonoImage = &nsBlendMonoImage0888_br; - } - } - else { - sAvailable = PR_FALSE; - NS_ASSERTION(0, "X11AlphaBlend: unsupported framebuffer depth"); - goto nsX11AlphaBlend__InitLibrary_error; - } - return sAvailable; - -nsX11AlphaBlend__InitLibrary_error: - // clean everything up but note that init was called - FreeGlobals(); - sInited = PR_TRUE; - return(sAvailable); -} - -nscolor -nsX11AlphaBlend::PixelToNSColor(unsigned long aPixel) -{ - nscolor color = (*sPixelToNSColor)(aPixel); - return color; -} - -/////////////////////////////////////////////////////////////////////// -// -// miscellaneous routines in alphabetic order -// -/////////////////////////////////////////////////////////////////////// - -#ifdef DEBUG -void -AADrawBox(XImage *aXImage, - PRInt32 aX1, PRInt32 aY1, - PRInt32 aWidth, PRInt32 aHeight, - nscolor aColor, PRUint8 aAlpha) -{ - PRInt32 i; - blendPixel blendPixelFunc = nsX11AlphaBlend::GetBlendPixel(); - if (aWidth<=0 || aHeight<=0) - return; - for (i=1; i win_width) { - copy_width = MIN(copy_width, (int)win_width - (aX+x_skip)); - any_offscreen = PR_TRUE; - } - if ((PRUint32)(aY+y_skip+aHeight) > win_height) { - copy_height = MIN(copy_height, (int)win_height - (aY+y_skip)); - any_offscreen = PR_TRUE; - } - - PRUint32 root_win_width, root_win_height; - root_win_width = DisplayWidth(aDisplay, aScreen); - root_win_height = DisplayHeight(aDisplay, aScreen); - - if ((PRUint32)(aX+x_skip+aWidth) > root_win_width) { - copy_width = MIN(copy_width, (int)root_win_width - (aX+x_skip)); - any_offscreen = PR_TRUE; - } - if ((PRUint32)(aY+y_skip+aHeight) > root_win_height) { - copy_height = MIN(copy_height, (int)root_win_height - (aY+y_skip)); - any_offscreen = PR_TRUE; - } - if ((copy_width<=0) || (copy_height<=0)) - return nsnull; // nothing visible - - // get the background image - // if any part is off screen XGetImage will fail, so we XCreateImage - // the image and use XGetSubImage to get the available background pixels - if (any_offscreen) { - char *data = (char *)nsMemory::Alloc(aWidth * aHeight * sBytesPerPixel); - if (!data) { - return nsnull; - } - XImage *super_ximage = XCreateImage(aDisplay, - DefaultVisual(aDisplay, aScreen), - DefaultDepth(aDisplay, aScreen), ZPixmap, - 0, data, aWidth, aHeight, - sBitmapPad, aWidth*sBytesPerPixel); - if (!super_ximage) { - NS_ASSERTION(super_ximage, "failed to create the super image"); - return nsnull; - } - ximage = XGetSubImage(aDisplay, aDrawable, - aX+x_skip, aY+y_skip, - copy_width, copy_height, - AllPlanes, ZPixmap, super_ximage, x_skip, y_skip); - if (!ximage) { - NS_ASSERTION(ximage, "failed to get the sub image"); - XDestroyImage(super_ximage); - return nsnull; - } - ximage = super_ximage; - } - else { - ximage = XGetImage(aDisplay, aDrawable, aX, aY, aWidth, aHeight, - AllPlanes, ZPixmap); - } - - NS_ASSERTION(ximage, "failed to get the image"); - return ximage; -} - -// -// 24 bit color, accessed in a 32 bit number -// -static void -nsBlendMonoImage0888(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint32 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - NS_ASSERTION(((ximage->data-(char*)0)&3)==0,"possible alignment error"); - NS_ASSERTION((ximage->bytes_per_line&3)==0,"possible alignment error"); - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 4*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row>16)&0xFF) * dst_a)) >> 8; - PRUint32 green = ((g*src_a) + (((dst_pixel>>8) &0xFF) * dst_a)) >> 8; - PRUint32 blue = ((b*src_a) + (( dst_pixel &0xFF) * dst_a)) >> 8; - *image_p = hibits | (red << 16) | (green << 8) | blue; - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -// -// 24 bit color, accessed in a 32 bit number -// -static void -nsBlendMonoImage0888_br(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint32 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 4*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row> 8) &0xFF) * dst_a)) >> 8; - PRUint32 green = ((g*src_a) + (((dst_pixel>>16) &0xFF) * dst_a)) >> 8; - PRUint32 blue = ((b*src_a) + (((dst_pixel>>24) &0xFF) * dst_a)) >> 8; - *image_p = (blue << 24) | (green << 16) + (red << 8) | lowbits; - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -// -// 15 bit color, accessed in a 16 bit number -// -static void -nsBlendMonoImage555(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint16 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 2*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row> 3); - // the long version - //(((r>>3)&0x1F)<<10) | (((g>>3)&0x1F)<<5) | (((b>>3)&0x1F)); - continue; - } - dst_a = 255 - src_a; - - PRUint16 dst_pixel = *image_p; - PRUint16 red = ((r*src_a) + (((dst_pixel>>7)&0xF8) * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (((dst_pixel>>2)&0xF8) * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (((dst_pixel<<3)&0xF8) * dst_a)) >> 8; - *image_p = ((red&0xF8)<<7) | ((green&0xF8)<<2) | ((blue) >> 3); - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -// -// 15 bit color, accessed in a 16 bit number, byte reversed -// -static void -nsBlendMonoImage555_br(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint16 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 2*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row> 1) | - ((g&0xC0)>> 6) | ((g&0x38)<<10) | - ((b&0xF8)<< 5); - continue; - } - dst_a = 255 - src_a; - - PRUint16 dst_pixel = *image_p; - // unreversed: --:R7:R6:R5:R4:R3:G7:G6 G5:G4:G3:B7:B6:B5:B4:B3 - // reversed: G5:G4:G3:B7:B6:B5:B4:B3 --:R7:R6:R5:R4:R3:G7:G6 - PRUint16 pixel_r = (dst_pixel>>1) & 0xF8; - PRUint16 pixel_g = ((dst_pixel<<6) & 0xC0) | ((dst_pixel>>10) & 0x38); - PRUint16 pixel_b = (dst_pixel>>5) & 0xF8; - - PRUint16 red = ((r*src_a) + (pixel_r * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (pixel_g * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (pixel_b * dst_a)) >> 8; - *image_p = ((red &0xF8)>> 1) | - ((green&0xC0)>> 6) | ((green&0x38)<<10) | - ((blue &0xF8)<< 5); - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -// -// 16 bit color, accessed in a 16 bit number -// -static void -nsBlendMonoImage565(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint16 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 2*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row> 3); - continue; - } - dst_a = 255 - src_a; - - PRUint32 dst_pixel = *image_p; - PRUint16 red = ((r*src_a) + (((dst_pixel>>8)&0xF8) * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (((dst_pixel>>3)&0xFC) * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (((dst_pixel<<3)&0xF8) * dst_a)) >> 8; - *image_p = ((red&0xF8)<<8) | ((green&0xFC)<<3) | ((blue) >> 3); - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -// -// 16 bit color, accessed in a 16 bit number, byte reversed -// -static void -nsBlendMonoImage565_br(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint16 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 2*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row> 5) | ((g&0x1C)<<11) | - ((b&0xF8)<< 5); - continue; - } - dst_a = 255 - src_a; - - PRUint16 dst_pixel = *image_p; - // unreversed: R7:R6:R5:R4:R3:G7:G6:G5 G4:G3:G2:B7:B6:B5:B4:B3 - // reversed: G4:G3:G2:B7:B6:B5:B4:B3 R7:R6:R5:R4:R3:G7:G6:G5 - PRUint16 pixel_r = (dst_pixel) & 0xF8; - PRUint16 pixel_g = ((dst_pixel<<5) & 0xE0) | ((dst_pixel>>11) & 0x1C); - PRUint16 pixel_b = (dst_pixel>>5) & 0xF8; - - PRUint16 red = ((r*src_a) + (pixel_r * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (pixel_g * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (pixel_b * dst_a)) >> 8; - *image_p = (red &0xF8) | - ((green&0xE0)>> 5) | ((green&0x1C)<<11) | - ((blue &0xF8)<< 5); - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -// -// 24 bit color, accessed in a 3*8 bit numbers, little endian -// -static void -nsBlendMonoImage888_lsb(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint32 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 3*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row> 8; - image_p[1] = ((g*src_a) + (image_p[1]*dst_a)) >> 8; - image_p[0] = ((b*src_a) + (image_p[0]*dst_a)) >> 8; - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -// -// 24 bit color, accessed in a 3*8 bit numbers, big endian -// -static void -nsBlendMonoImage888_msb(XImage *ximage, nsAntiAliasedGlyph * glyph, - PRUint8 *aWeightTable, nscolor color, int xOff, int yOff) -{ - PRUint32 src_a, dst_a; - - int xfer_width = MIN((int)glyph->GetWidth(), ximage->width-xOff); - int xfer_height = MIN((int)glyph->GetHeight(), ximage->height-yOff); - NS_ASSERTION(xfer_width==(int)glyph->GetWidth(), "image not wide enough"); - NS_ASSERTION(xfer_height==(int)glyph->GetHeight(), "image not tall enough"); - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *glyph_p = glyph->GetBuffer(); - PRUint8 *imageLineStart = (PRUint8 *)ximage->data - + 3*xOff + (yOff * ximage->bytes_per_line); - - for (int row=0; row> 8; - image_p[1] = ((g*src_a) + (image_p[1]*dst_a)) >> 8; - image_p[2] = ((b*src_a) + (image_p[0]*dst_a)) >> 8; - } - glyph_p += -xfer_width + glyph->GetBufferWidth(); - imageLineStart += ximage->bytes_per_line; - } -} - -#ifdef DEBUG -static void -nsBlendPixel0888(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint32 *pPixel = ((PRUint32*)(ximage->data+(y*ximage->bytes_per_line)))+x; - PRUint32 pixel = *pPixel; - PRUint32 hibits = pixel & 0xFF000000; - if (src_a >= 255) { - *pPixel = hibits | (r << 16) | (g << 8) | b; - return; - } - - PRUint32 dst_a = 255 - src_a; - PRUint32 red = ((r*src_a) + (((pixel>>16)&0xFF) * dst_a)) >> 8; - PRUint32 green = ((g*src_a) + (((pixel>>8) &0xFF) * dst_a)) >> 8; - PRUint32 blue = ((b*src_a) + (( pixel &0xFF) * dst_a)) >> 8; - *pPixel = hibits | (red << 16) | (green << 8) | blue; -} - -static void -nsBlendPixel0888_br(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint32 *pPixel = ((PRUint32*)(ximage->data+(y*ximage->bytes_per_line)))+x; - PRUint32 pixel = *pPixel; - PRUint32 lowbits = pixel & 0xFF000000; - if (src_a >= 255) { - *pPixel = lowbits | (b << 24) | (g << 16) | (r<<8); - return; - } - - PRUint32 dst_a = 255 - src_a; - PRUint32 red = ((r*src_a) + (((pixel>>16)&0xFF) * dst_a)) >> 8; - PRUint32 green = ((g*src_a) + (((pixel>>8) &0xFF) * dst_a)) >> 8; - PRUint32 blue = ((b*src_a) + (( pixel &0xFF) * dst_a)) >> 8; - *pPixel = lowbits | (blue << 24) | (green << 16) | (red<<8); -} - -static void -nsBlendPixel555(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint16 *pPixel = ((PRUint16*)(ximage->data+(y*ximage->bytes_per_line)))+x; - PRUint16 pixel = *pPixel; - if (src_a >= 255) { - *pPixel = ((r&0xF8)<<7) + ((g&0xF8)<<2) + ((b)>>3); - return; - } - - PRUint16 dst_a = 255 - src_a; - - PRUint16 red = ((r*src_a) + (((pixel>>7) &0xF8) * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (((pixel>>2) &0xF8) * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (((pixel<<3) &0xF8) * dst_a)) >> 8; - *pPixel = ((red&0xF8)<<7) + ((green&0xF8)<<2) + ((blue)>>3); -} - -static void -nsBlendPixel555_br(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint16 *pPixel = ((PRUint16*)(ximage->data+(y*ximage->bytes_per_line)))+x; - PRUint16 pixel = *pPixel; - if (src_a >= 255) { - *pPixel = ((r&0xF8) >> 1) | - ((g&0xC0)>> 6) | ((g&0x38)<<10) | - ((b&0xF8)<< 5); - return; - } - - PRUint16 dst_a = 255 - src_a; - // unreversed: --:R7:R6:R5:R4:R3:G7:G6 G5:G4:G3:B7:B6:B5:B4:B3 - // reversed: G5:G4:G3:B7:B6:B5:B4:B3 --:R7:R6:R5:R4:R3:G7:G6 - PRUint16 pixel_r = (pixel>>1) & 0xF8; - PRUint16 pixel_g = ((pixel<<6) & 0xC0) | ((pixel>>10) & 0x38); - PRUint16 pixel_b = (pixel>>5) & 0xF8; - - PRUint16 red = ((r*src_a) + (pixel_r * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (pixel_g * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (pixel_b * dst_a)) >> 8; - *pPixel = ((red&0xF8) >> 1) | - ((green&0xC0)>> 6) | ((green&0x38)<<10) | - ((blue&0xF8)<< 5); -} - -static void -nsBlendPixel565(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint16 *pPixel = ((PRUint16*)(ximage->data+(y*ximage->bytes_per_line)))+x; - PRUint16 pixel = *pPixel; - if (src_a >= 255) { - *pPixel = ((r&0xF8)<<8) + ((g&0xFC)<<3) + ((b)>>3); - return; - } - - PRUint16 dst_a = 255 - src_a; - - PRUint16 red = ((r*src_a) + (((pixel>>8) &0xF8) * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (((pixel>>3) &0xFC) * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (((pixel<<3) &0xF8) * dst_a)) >> 8; - *pPixel = ((red&0xF8)<<8) + ((green&0xFC)<<3) + ((blue)>>3); -} - -static void -nsBlendPixel565_br(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint16 *pPixel = ((PRUint16*)(ximage->data+(y*ximage->bytes_per_line)))+x; - PRUint16 pixel = *pPixel; - if (src_a >= 255) { - *pPixel = (r&0xF8) | - ((g&0xE0)>> 5) | ((g&0x1C)<<11) | - ((b&0xF8)<< 5); - return; - } - - PRUint16 dst_a = 255 - src_a; - // unreversed: R7:R6:R5:R4:R3:G7:G6:G5 G4:G3:G2:B7:B6:B5:B4:B3 - // reversed: G4:G3:G2:B7:B6:B5:B4:B3 R7:R6:R5:R4:R3:G7:G6:G5 - PRUint16 pixel_r = (pixel) & 0xF8; - PRUint16 pixel_g = ((pixel<<5) & 0xE0) | ((pixel>>11) & 0x1C); - PRUint16 pixel_b = (pixel>>5) & 0xF8; - - PRUint16 red = ((r*src_a) + (pixel_r * dst_a)) >> 8; - PRUint16 green = ((g*src_a) + (pixel_g * dst_a)) >> 8; - PRUint16 blue = ((b*src_a) + (pixel_b * dst_a)) >> 8; - *pPixel = (red&0xF8) | - ((green&0xE0)>> 5) | ((green&0x1C)<<11) | - ((blue&0xF8)<< 5); -} - -static void -nsBlendPixel888_lsb(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *pPixel = ((PRUint8*)(ximage->data+(y*ximage->bytes_per_line))) + 3*x; - if (src_a >= 255) { - pPixel[2] = r; - pPixel[1] = g; - pPixel[0] = b; - return; - } - - PRUint32 dst_a = 255 - src_a; - pPixel[2] = ((r*src_a) + (pPixel[2] * dst_a)) >> 8; - pPixel[1] = ((g*src_a) + (pPixel[1] * dst_a)) >> 8; - pPixel[0] = ((b*src_a) + (pPixel[0] * dst_a)) >> 8; -} - -static void -nsBlendPixel888_msb(XImage *ximage, int x, int y, nscolor color, int src_a) -{ - NS_ASSERTION((src_a>=0)&&(src_a<=255), "Invalid alpha"); - if (src_a <= 0) - return; - - NS_ASSERTION(xwidth, "x out of bounds"); - NS_ASSERTION(yheight, "y out of bounds"); - if ((x >= ximage->width) || (y >= ximage->height)) - return; - - PRUint16 r = NS_GET_R(color); - PRUint16 g = NS_GET_G(color); - PRUint16 b = NS_GET_B(color); - - PRUint8 *pPixel = ((PRUint8*)(ximage->data+(y*ximage->bytes_per_line))) + 3*x; - if (src_a >= 255) { - pPixel[0] = r; - pPixel[1] = g; - pPixel[2] = b; - return; - } - - PRUint32 dst_a = 255 - src_a; - pPixel[0] = ((r*src_a) + (pPixel[0] * dst_a)) >> 8; - pPixel[1] = ((g*src_a) + (pPixel[1] * dst_a)) >> 8; - pPixel[2] = ((b*src_a) + (pPixel[2] * dst_a)) >> 8; -} -#endif - - -nscolor -nsPixelToNscolor555(unsigned long aPixel) -{ - int r = (aPixel>>7)&0xF8; - int g = (aPixel>>2)&0xF8; - int b = (aPixel<<3)&0xF8; - nscolor color = NS_RGB(r,g,b); - return color; -} - -nscolor -nsPixelToNscolor565(unsigned long aPixel) -{ - int r = (aPixel>>8)&0xF8; - int g = (aPixel>>3)&0xFC; - int b = (aPixel<<3)&0xF8; - nscolor color = NS_RGB(r,g,b); - return color; -} - -nscolor -nsPixelToNscolor888_lsb(unsigned long aPixel) -{ - int r = (aPixel>>16)&0xFF; - int g = (aPixel>> 8)&0xFF; - int b = (aPixel )&0xFF; - nscolor color = NS_RGB(r,g,b); - return color; -} - -nscolor -nsPixelToNscolor888_msb(unsigned long aPixel) -{ - int r = (aPixel )&0xFF; - int g = (aPixel>> 8)&0xFF; - int b = (aPixel>>16)&0xFF; - nscolor color = NS_RGB(r,g,b); - return color; -} - diff --git a/gfx/src/x11shared/nsX11AlphaBlend.h b/gfx/src/x11shared/nsX11AlphaBlend.h deleted file mode 100644 index 951bfdd50dcc..000000000000 --- a/gfx/src/x11shared/nsX11AlphaBlend.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Netscape.com code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsX11AlphaBlend_h__ -#define nsX11AlphaBlend_h__ - -#include -#include "nsColor.h" - -class nsAntiAliasedGlyph; - -#ifdef DEBUG -#ifndef DEBUG_SHOW_GLYPH_BOX -# define DEBUG_SHOW_GLYPH_BOX 0 -#endif -void AADrawBox(XImage *, PRInt32, PRInt32, PRInt32, PRInt32, nscolor, PRUint8); -#if DEBUG_SHOW_GLYPH_BOX -# define DEBUG_AADRAWBOX(i,x,y,w,h,r,g,b,a) \ - PR_BEGIN_MACRO \ - nscolor color NS_RGB((r),(g),(b)); \ - AADrawBox((i), (x), (y), (w), (h), color, (a)); \ - PR_END_MACRO -#else -# define DEBUG_AADRAWBOX(i,x,y,w,h,r,g,b,a) -#endif -#endif - -void nsX11AlphaBlendFreeGlobals(void); -nsresult nsX11AlphaBlendInitGlobals(Display *dsp); - - -typedef void (*blendGlyph)(XImage *, nsAntiAliasedGlyph *, PRUint8*, - nscolor, int, int); -typedef void (*blendPixel)(XImage *, int, int, nscolor, int); -typedef nscolor (*pixelToNSColor)(unsigned long aPixel); - -/////////////////////////////////////////////////////////////////////// -// -// class nsX11AlphaBlend class definition -// -/////////////////////////////////////////////////////////////////////// -class nsX11AlphaBlend { -public: - inline static PRBool CanAntiAlias() { return sAvailable; }; - inline static blendPixel GetBlendPixel() { return sBlendPixel; }; - inline static blendGlyph GetBlendGlyph() { return sBlendMonoImage; }; - - static XImage* GetXImage(PRUint32 width, PRUint32 height); - static void FreeGlobals(); - static nsresult InitGlobals(Display *dsp); - static XImage* GetBackground(Display *, int, Drawable, - PRInt32, PRInt32, PRUint32, PRUint32); - static nscolor PixelToNSColor(unsigned long aPixel); - -protected: - static void ClearGlobals(); - static void ClearFunctions(); - static PRBool InitLibrary(Display *dsp); - - static PRBool sAvailable; - static PRUint16 sBitmapPad; - static PRUint16 sBitsPerPixel; - static blendGlyph sBlendMonoImage; - static blendPixel sBlendPixel; - static PRUint16 sBytesPerPixel; - static int sDepth; - static PRBool sInited; - static pixelToNSColor sPixelToNSColor; -}; - -#endif /* nsX11AlphaBlend_h__ */ diff --git a/gfx/src/x11shared/nsXFont.h b/gfx/src/x11shared/nsXFont.h deleted file mode 100644 index c62272da3dde..000000000000 --- a/gfx/src/x11shared/nsXFont.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsXFont_h__ -#define nsXFont_h__ - -class nsXFont { -public: - virtual ~nsXFont() { }; - virtual void DrawText8(GdkDrawable *Drawable, GdkGC *GC, PRInt32, - PRInt32, const char *, PRUint32) = 0; - virtual void DrawText16(GdkDrawable *Drawable, GdkGC *GC, PRInt32, - PRInt32, const XChar2b *, PRUint32) = 0; - virtual PRBool GetXFontProperty(Atom, unsigned long *) = 0; - virtual XFontStruct *GetXFontStruct() = 0; - inline PRBool IsSingleByte() { return mIsSingleByte; }; - virtual PRBool LoadFont() = 0; - virtual void TextExtents8(const char *, PRUint32, PRInt32*, PRInt32*, - PRInt32*, PRInt32*, PRInt32*) = 0; - virtual void TextExtents16(const XChar2b *, PRUint32, PRInt32*, - PRInt32*, PRInt32*, PRInt32*, PRInt32*) =0; - virtual PRInt32 TextWidth8(const char *, PRUint32) = 0; - virtual PRInt32 TextWidth16(const XChar2b *, PRUint32) = 0; -//protected: - virtual void UnloadFont() = 0; -protected: - PRBool mIsSingleByte; -}; - -#endif /* nsXFont_h__ */ diff --git a/gfx/src/x11shared/nsXFontAAScaledBitmap.cpp b/gfx/src/x11shared/nsXFontAAScaledBitmap.cpp deleted file mode 100644 index 703233e26f01..000000000000 --- a/gfx/src/x11shared/nsXFontAAScaledBitmap.cpp +++ /dev/null @@ -1,1352 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include "gfx-config.h" -#include "nscore.h" -#include "nsXFontAAScaledBitmap.h" -#include "nsRenderingContextGTK.h" -#include "nsX11AlphaBlend.h" - -#include -#include - -#include "nsHashtable.h" - -#define IMAGE_BUFFER_SIZE 2048 - -#ifdef DEBUG - static PRBool dodump = 0; -# define DEBUG_DUMP(x) if (dodump) {dodump=0; x; } -#else -# define DEBUG_DUMP(x) -#endif - -#define DEBUG_SHOW_GLYPH_BOX 0 -#if DEBUG_SHOW_GLYPH_BOX -# define DEBUG_AADRAWBOX(i,x,y,w,h,r,g,b,a) \ - PR_BEGIN_MACRO \ - nscolor color NS_RGB((r),(g),(b)); \ - AADrawBox((i), (x), (y), (w), (h), color, (a)); \ - PR_END_MACRO -#else -# define DEBUG_AADRAWBOX(i,x,y,w,h,r,g,b,a) -#endif - -void dump_byte_table(PRUint8 *table, int width, int height); - -static void scale_image(nsAntiAliasedGlyph *, nsAntiAliasedGlyph *); -static void scale_imageAntiJag(nsAntiAliasedGlyph *, nsAntiAliasedGlyph *); -static void WeightTableInitLinearCorrection(PRUint8*, PRUint8, double); - -Display *nsXFontAAScaledBitmap::sDisplay = nsnull; -GC nsXFontAAScaledBitmap::sBackgroundGC = nsnull; -PRUint8 nsXFontAAScaledBitmap::sWeightedScaleDarkText[256]; -PRUint8 nsXFontAAScaledBitmap::sWeightedScaleLightText[256]; - -// -// Anti-Aliased Scaled Bitmap Fonts (AASB) -// -// AASB fonts are made by taking a regular X font, drawing the desired -// glyph(s) off screen, bringing the pixels down to the client, and then -// scaling the bits using anti-aliasing to get a correctly weighted -// pixels in the scaled version. The AASB glyphs are visually correct -// but tend to be a bit weak and blurry. -// -// To make the glyphs stronger and sharper the pixels are adjusted. -// -// One strategy would be to lighten the light pixels and darken the -// dark pixels. Lightening the light pixels makes "thin" lines -// disappear completely so this is not done. -// -// To darken the dark pixels the code increases the value of the pixels -// (above a minimum value). -// -// for (i=0; i<256; i++) { -// if (i < min_value) -// val = i; -// else -// val = i + ((i - min_value)*gain); -// -// (of course limiting val to between 0 and 255 inclusive) -// -// Dark text (eg: black glyphs on a white background) is weighted -// separately from light text (eg: white text on a blue background). -// Selected text is white text on a blue background. The contrast -// between white text on a blue background is not as strong a black -// black text on a white background so light colored text is -// "sharpened" more than dark text. - -PRUint8 gAASBDarkTextMinValue = 64; -double gAASBDarkTextGain = 0.6; -PRUint8 gAASBLightTextMinValue = 64; -double gAASBLightTextGain = 1.3; - -PRBool -nsXFontAAScaledBitmap::DisplayIsLocal(Display *aDisplay) -{ - // if shared memory works then the display is local - if (gdk_get_use_xshm()) - return PR_TRUE; - - return PR_FALSE; - -} - -void -nsXFontAAScaledBitmap::DrawText8(GdkDrawable *aDrawable, GdkGC *aGC, - PRInt32 aX, PRInt32 aY, - const char *aString, PRUint32 aLength) -{ - DrawText8or16(aDrawable, aGC, aX, aY, (void*)aString, aLength); -} - -void -nsXFontAAScaledBitmap::DrawText16(GdkDrawable *aDrawable, GdkGC *aGC, - PRInt32 aX, PRInt32 aY, - const XChar2b *aString, PRUint32 aLength) -{ - DrawText8or16(aDrawable, aGC, aX, aY, (void*)aString, aLength); -} - -// -// We save code space by merging the 8 and 16 bit drawing routines. -// The signature of this fuction is vague but that is okay since -// it is only used internally by nsXFontAAScaledBitmap and not -// presented as an API. -// -void -nsXFontAAScaledBitmap::DrawText8or16(GdkDrawable *aDrawable, GdkGC *aGC, - PRInt32 aX, PRInt32 aY, - void *a8or16String, PRUint32 aLength) -{ - // make the indeterminate input variables determinate - const char *string8 = (const char *)a8or16String; - const XChar2b *string16 = (const XChar2b *)a8or16String; - -#if DEBUG_SHOW_GLYPH_BOX - // grey shows image size - // red shows character cells - // green box shows text ink -#endif - - if (aLength < 1) { - return; - } - - // - // Get a area guaranteed to be big enough. - // - // This can be bigger than necessary but for debuggability - // this code can draw the char cells. Calculating the - // exact size needed both the character cells and - // pixels to the left and right of the character cells - // is quite messy. - // - PRUint32 image_width = (mScaledMax.width * aLength) + mScaledMax.lbearing; - PRUint32 image_height = mScaledMax.ascent+mScaledMax.descent; - PRInt32 x_pos = mScaledMax.lbearing; - - Drawable win = GDK_WINDOW_XWINDOW(aDrawable); - GC gc = GDK_GC_XGC(aGC); - XGCValues values; - if (!XGetGCValues(mDisplay, gc, GCForeground, &values)) { - NS_ASSERTION(0, "failed to get foreground pixel"); - return; - } - nscolor color = nsX11AlphaBlend::PixelToNSColor(values.foreground); - - // weight dark text differently from light text - PRUint32 color_val = NS_GET_R(color) + NS_GET_G(color) + NS_GET_B(color); - PRUint8 *weight_table; - if ((NS_GET_R(color)>200) || (NS_GET_R(color)>200) || (NS_GET_R(color)>200) - || (color_val>3*128)) - weight_table = sWeightedScaleLightText; - else - weight_table = sWeightedScaleDarkText; - - // - // Get the background - // - XImage *sub_image = nsX11AlphaBlend::GetBackground(mDisplay, mScreen, win, - aX-mScaledMax.lbearing, aY-mScaledMax.ascent, - image_width, image_height); - if (sub_image==nsnull) { -#ifdef DEBUG - // complain if the requested area is not completely off screen - int win_width = DisplayWidth(mDisplay, mScreen); - int win_height = DisplayHeight(mDisplay, mScreen); - if (((int)(aX-mScaledMax.lbearing+image_width) > 0) // not hidden to left - && ((int)(aX-mScaledMax.lbearing) < win_width) // not hidden to right - && ((int)(aY-mScaledMax.ascent+image_height) > 0)// not hidden to top - && ((int)(aY-mScaledMax.ascent) < win_height)) // not hidden to bottom - { - NS_ASSERTION(sub_image, "failed to get the image"); - } -#endif - return; - } - -#if DEBUG_SHOW_GLYPH_BOX - DEBUG_AADRAWBOX(sub_image,0,0,image_width,image_height,0,0,0,255/4); - int lbearing, rbearing, width, ascent, descent; - if (mIsSingleByte) - TextExtents8(aString8, aLength, &lbearing, &rbearing, &width, - &ascent, &descent); - else - TextExtents16(aString16, aLength, &lbearing, &rbearing, &width, - &ascent, &descent); - - DEBUG_AADRAWBOX(sub_image, x_pos+lbearing, mScaledMax.ascent-ascent, - rbearing-lbearing, ascent+descent, 0,255,0, 255/2); -#endif - - // - // Get aa-scaled glyphs and blend with background - // - blendGlyph blendGlyph = nsX11AlphaBlend::GetBlendGlyph(); - for (PRUint32 i=0; iGetBorder()==0, - "do not support non-zero border"); - DEBUG_DUMP((dump_byte_table(scaled_glyph->GetBuffer(), - scaled_glyph->GetBufferWidth(), - scaled_glyph->GetBufferHeight()))); - // - // blend the aa-glyph onto the background - // - (*blendGlyph)(sub_image, scaled_glyph, weight_table, color, - x_pos + scaled_glyph->GetLBearing(), 0); - - DEBUG_DUMP((dump_XImage_blue_data(sub_image))); - x_pos += scaled_glyph->GetAdvance(); - } - DEBUG_DUMP((dump_XImage_blue_data(sub_image))); - - // - // Send it to the display - // - XPutImage(mDisplay, win, gc, sub_image, - 0, 0, aX-mScaledMax.lbearing, aY-mScaledMax.ascent, - image_width, image_height); - XDestroyImage(sub_image); -} - -void -nsXFontAAScaledBitmap::FreeGlobals() -{ - if (sBackgroundGC) { - XFreeGC(sDisplay, sBackgroundGC); - sBackgroundGC = nsnull; - } - sDisplay = nsnull; -} - -static PRBool -FreeGlyphHash(nsHashKey* aKey, void* aData, void* aClosure) -{ - delete (nsAntiAliasedGlyph *)aData; - - return PR_TRUE; -} - -PRBool -nsXFontAAScaledBitmap::GetScaledGreyImage(const char *aChar, - nsAntiAliasedGlyph **aGreyImage) -{ - XChar2b *aChar2b = nsnull; - PRUint32 antiJagPadding; - XImage *ximage; - nsAntiAliasedGlyph *scaled_image; - PRUnichar charKey[2]; - - // get the char key - if (mIsSingleByte) - charKey[0] = (PRUnichar)*aChar; - else { - aChar2b = (XChar2b *)aChar; - charKey[0] = aChar2b->byte1<<8 | aChar2b->byte2; - } - charKey[1] = 0; - nsStringKey key(charKey, 1); - - // look in the cache for the glyph image - scaled_image = (nsAntiAliasedGlyph*)mGlyphHash->Get(&key); - if (!scaled_image) { - // get the char metrics - int direction, font_ascent, font_descent; - XCharStruct charMetrics; - if (mIsSingleByte) - XTextExtents(mUnscaledFontInfo, aChar, 1, &direction, - &font_ascent, &font_descent, &charMetrics); - else - XTextExtents16(mUnscaledFontInfo, aChar2b,1, &direction, - &font_ascent, &font_descent, &charMetrics); - - // figure the amount to scale - PRInt32 left_edge = GLYPH_LEFT_EDGE(&charMetrics); - PRInt32 right_edge = GLYPH_RIGHT_EDGE(&charMetrics); - PRUint32 unscaled_width = right_edge - left_edge; - NS_ASSERTION(unscaled_width<=mUnscaledMax.width, "unexpected glyph width"); - - // clear the bitmap - XFillRectangle(mDisplay, mUnscaledBitmap, sBackgroundGC, 0, 0, - unscaled_width, mUnscaledMax.height); - // draw the char - if (mIsSingleByte) - XDrawString(mDisplay, mUnscaledBitmap, mForegroundGC, - -left_edge, mUnscaledMax.ascent, aChar, 1); - else - XDrawString16(mDisplay, mUnscaledBitmap, mForegroundGC, - -left_edge, mUnscaledMax.ascent, aChar2b, 1); - // get the pixels - ximage = XGetImage(mDisplay, mUnscaledBitmap, - 0, 0, unscaled_width, mUnscaledMax.height, - AllPlanes, ZPixmap); - NS_ASSERTION(ximage, "failed to XGetSubImage()"); - if (!ximage) { - return PR_FALSE; - } - DEBUG_DUMP((dump_XImage_blue_data(ximage))); - - // must pad when anti-jagging - if (mRatio < 1.25) - antiJagPadding = 0; - else - antiJagPadding = 2; // this may change if the anti-jagging code changes - - // create the empty nsAntiAliasedGlyph - nsAntiAliasedGlyph unscaled_image(unscaled_width, mUnscaledMax.height, - antiJagPadding); - PRUint8 buf[IMAGE_BUFFER_SIZE]; // try to use the stack for data - if (!unscaled_image.Init(buf, IMAGE_BUFFER_SIZE)) { - NS_ASSERTION(0, "failed to Init() unscaled_image"); - XDestroyImage(ximage); - return PR_FALSE; - } - - // - // get ready to scale - // - unscaled_image.SetImage(&charMetrics, ximage); - DEBUG_DUMP((dump_byte_table(unscaled_image.GetBuffer(), - unscaled_image.GetBufferWidth(), - unscaled_image.GetBufferHeight()))); - XDestroyImage(ximage); - - // - // Create the scaled glyph - // - GlyphMetrics glyphMetrics; - glyphMetrics.width = SCALED_SIZE(unscaled_width); - glyphMetrics.height = SCALED_SIZE(mUnscaledMax.height); - glyphMetrics.lbearing = SCALED_SIZE(left_edge); - glyphMetrics.rbearing = SCALED_SIZE(right_edge); - glyphMetrics.advance = SCALED_SIZE(charMetrics.width); - glyphMetrics.ascent = SCALED_SIZE(charMetrics.ascent); - glyphMetrics.descent = SCALED_SIZE(charMetrics.descent); - - scaled_image = new nsAntiAliasedGlyph(SCALED_SIZE(unscaled_width), - SCALED_SIZE(mUnscaledMax.height), 0); - NS_ASSERTION(scaled_image, "failed to create scaled_image"); - if (!scaled_image) { - return PR_FALSE; - } - if (!scaled_image->Init()) { - NS_ASSERTION(0, "failed to initialize scaled_image"); - delete scaled_image; - return PR_FALSE; - } - scaled_image->SetSize(&glyphMetrics); - - // - // scale - // - if (antiJagPadding==0) - scale_image(&unscaled_image, scaled_image); - else - scale_imageAntiJag(&unscaled_image, scaled_image); - - DEBUG_DUMP((dump_byte_table(scaled_image->GetBuffer(), - scaled_image->GetBufferWidth(), - scaled_image->GetBufferHeight()))); - - // store in hash - mGlyphHash->Put(&key, scaled_image); - } - *aGreyImage = scaled_image; - return PR_TRUE; -} - -PRBool -nsXFontAAScaledBitmap::GetXFontProperty(Atom aAtom, unsigned long *aValue) -{ - unsigned long val; - PRBool rslt = ::XGetFontProperty(mUnscaledFontInfo, aAtom, &val); - if (!rslt) - return PR_FALSE; - - switch (aAtom) { - case XA_X_HEIGHT: - if (val >= 0x00ffffff) {// Bug 43214: arbitrary to exclude garbage values - return PR_FALSE; - } - case XA_SUBSCRIPT_Y: - case XA_SUPERSCRIPT_Y: - case XA_UNDERLINE_POSITION: - case XA_UNDERLINE_THICKNESS: - *aValue = (unsigned long)SCALED_SIZE(val); - break; - default: - *aValue = val; - } - return rslt; -} - -XFontStruct * -nsXFontAAScaledBitmap::GetXFontStruct() -{ - NS_ASSERTION(mGdkFont, "GetXFontStruct called before font loaded"); - if (mGdkFont==nsnull) - return nsnull; - - return &mScaledFontInfo; -} - -PRBool -nsXFontAAScaledBitmap::InitGlobals(Display *aDisplay, int aScreen) -{ - Window root_win; - - sDisplay = aDisplay; // used to free shared sBackgroundGC - - // if not a local display then might be slow so don't run - if (!DisplayIsLocal(aDisplay)) { - goto cleanup_and_return; - } - - root_win = RootWindow(sDisplay, aScreen); - sBackgroundGC = XCreateGC(sDisplay, root_win, 0, NULL); - NS_ASSERTION(sBackgroundGC, "failed to create sBackgroundGC"); - if (!sBackgroundGC) { - goto cleanup_and_return; - } - XSetForeground(sDisplay, sBackgroundGC, 0); - - WeightTableInitLinearCorrection(sWeightedScaleDarkText, - gAASBDarkTextMinValue, gAASBDarkTextGain); - WeightTableInitLinearCorrection(sWeightedScaleLightText, - gAASBLightTextMinValue, gAASBLightTextGain); - return PR_TRUE; - -cleanup_and_return: - if (sBackgroundGC) { - XFreeGC(sDisplay, sBackgroundGC); - sBackgroundGC = nsnull; - } - - return PR_FALSE; -} - -PRBool -nsXFontAAScaledBitmap::LoadFont() -{ - NS_ASSERTION(!mAlreadyLoaded, "LoadFont called more than once"); - mAlreadyLoaded = PR_TRUE; - - if (!mGdkFont) - return PR_FALSE; - mUnscaledFontInfo = (XFontStruct *)GDK_FONT_XFONT(mGdkFont); - - XFontStruct *usfi = mUnscaledFontInfo; - XFontStruct *sfi = &mScaledFontInfo; - - mIsSingleByte = (usfi->min_byte1 == 0) && (usfi->max_byte1 == 0); - - mUnscaledMax.width = MAX(usfi->max_bounds.rbearing,usfi->max_bounds.width); - mUnscaledMax.width -= MIN(usfi->min_bounds.lbearing, 0); - mUnscaledMax.height = usfi->max_bounds.ascent + usfi->max_bounds.descent; - mUnscaledMax.lbearing = usfi->max_bounds.lbearing; - mUnscaledMax.rbearing = usfi->max_bounds.rbearing; - mUnscaledMax.advance = usfi->max_bounds.width; - mUnscaledMax.ascent = usfi->max_bounds.ascent; - mUnscaledMax.descent = usfi->max_bounds.descent; - - mScaledMax.width = SCALED_SIZE(mUnscaledMax.width); - mScaledMax.lbearing = SCALED_SIZE(mUnscaledMax.lbearing); - mScaledMax.rbearing = SCALED_SIZE(mUnscaledMax.rbearing); - mScaledMax.advance = SCALED_SIZE(mUnscaledMax.width); - mScaledMax.ascent = SCALED_SIZE(mUnscaledMax.ascent); - mScaledMax.descent = SCALED_SIZE(mUnscaledMax.ascent + mUnscaledMax.descent) - - SCALED_SIZE(mUnscaledMax.ascent); - mScaledMax.height = mScaledMax.ascent + mScaledMax.descent; - - // - // Scale the XFontStruct - // - sfi->fid = 0; - sfi->direction = usfi->direction; - sfi->min_char_or_byte2 = usfi->min_char_or_byte2; - sfi->max_char_or_byte2 = usfi->max_char_or_byte2; - sfi->min_byte1 = usfi->min_byte1; - sfi->max_byte1 = usfi->max_byte1; - sfi->all_chars_exist = usfi->all_chars_exist; - sfi->default_char = usfi->default_char; - sfi->n_properties = 0; - sfi->properties = nsnull; - sfi->ext_data = nsnull; - - sfi->min_bounds.lbearing = SCALED_SIZE(usfi->min_bounds.lbearing); - sfi->min_bounds.rbearing = SCALED_SIZE(usfi->min_bounds.rbearing); - sfi->min_bounds.width = SCALED_SIZE(usfi->min_bounds.width); - sfi->min_bounds.ascent = SCALED_SIZE(usfi->min_bounds.ascent); - sfi->min_bounds.descent = - SCALED_SIZE(usfi->min_bounds.ascent + usfi->min_bounds.descent) - - SCALED_SIZE(usfi->min_bounds.ascent); - sfi->min_bounds.attributes = usfi->min_bounds.attributes; - - sfi->max_bounds.lbearing = SCALED_SIZE(usfi->max_bounds.lbearing); - sfi->max_bounds.rbearing = SCALED_SIZE(usfi->max_bounds.rbearing); - sfi->max_bounds.width = SCALED_SIZE(usfi->max_bounds.width); - sfi->max_bounds.ascent = SCALED_SIZE(usfi->max_bounds.ascent); - sfi->max_bounds.descent = - SCALED_SIZE(usfi->max_bounds.ascent + usfi->max_bounds.descent) - - SCALED_SIZE(usfi->max_bounds.ascent); - sfi->max_bounds.attributes = usfi->max_bounds.attributes; - - sfi->per_char = nsnull; - sfi->ascent = SCALED_SIZE(usfi->ascent); - sfi->descent = SCALED_SIZE(usfi->descent); - - // - // need a unique foreground GC for each font size/face - // to use to draw the unscaled bitmap font - // - mForegroundGC = XCreateGC(mDisplay, RootWindow(mDisplay, mScreen), 0, NULL); - NS_ASSERTION(mForegroundGC, "failed to create mForegroundGC"); - if (!mForegroundGC) { - goto cleanup_and_return; - } - - XSetFont(mDisplay, mForegroundGC, usfi->fid); - XSetForeground(mDisplay, mForegroundGC, 0xFFFFFF); - - mUnscaledBitmap = XCreatePixmap(mDisplay, - RootWindow(mDisplay,DefaultScreen(mDisplay)), - mUnscaledMax.width, mUnscaledMax.height, - DefaultDepth(mDisplay, mScreen)); - if (!mUnscaledBitmap) - goto cleanup_and_return; - - mGlyphHash = new nsHashtable(); - if (!mGlyphHash) - goto cleanup_and_return; - - if (mGdkFont) { -#ifdef NS_FONT_DEBUG_LOAD_FONT - if (gFontDebug & NS_FONT_DEBUG_LOAD_FONT) { - printf("loaded %s\n", mName); - } -#endif - return PR_TRUE; - } - else - return PR_FALSE; - -cleanup_and_return: - if (mUnscaledFontInfo) { - mUnscaledFontInfo = nsnull; - } - if (mForegroundGC) { - XFreeGC(mDisplay, mForegroundGC); - mForegroundGC = nsnull; - } - if (mUnscaledBitmap) { - XFreePixmap(mDisplay, mUnscaledBitmap); - mUnscaledBitmap = nsnull; - } - if (mGlyphHash) { - delete mGlyphHash; - mGlyphHash = nsnull; - } - memset(&mScaledFontInfo, 0, sizeof(mScaledFontInfo)); - memset(&mUnscaledMax, 0, sizeof(mUnscaledMax)); - memset(&mScaledMax, 0, sizeof(mScaledMax)); - return PR_FALSE; -} - -nsXFontAAScaledBitmap::nsXFontAAScaledBitmap(Display *aDisplay, - int aScreen, - GdkFont *aGdkFont, - PRUint16 aSize, - PRUint16 aUnscaledSize) -{ - mAlreadyLoaded = PR_FALSE; - mDisplay = aDisplay; - mScreen = aScreen; - mGdkFont = ::gdk_font_ref(aGdkFont); - mUnscaledSize = aUnscaledSize; - mRatio = ((double)aSize)/((double)aUnscaledSize); - mIsSingleByte = 0; - mForegroundGC = nsnull; - mGlyphHash = nsnull; - mUnscaledBitmap = nsnull; - memset(&mScaledFontInfo, 0, sizeof(mScaledFontInfo)); - memset(&mUnscaledMax, 0, sizeof(mUnscaledMax)); - memset(&mScaledMax, 0, sizeof(mScaledMax)); -} - -void -nsXFontAAScaledBitmap::TextExtents8(const char *aString, PRUint32 aLength, - PRInt32* aLBearing, PRInt32* aRBearing, - PRInt32* aWidth, PRInt32* aAscent, - PRInt32* aDescent) -{ - TextExtents8or16((void *)aString, aLength, aLBearing, aRBearing, aWidth, - aAscent, aDescent); -} - -void -nsXFontAAScaledBitmap::TextExtents16(const XChar2b *aString, PRUint32 aLength, - PRInt32* aLBearing, PRInt32* aRBearing, - PRInt32* aWidth, PRInt32* aAscent, - PRInt32* aDescent) -{ - TextExtents8or16((void *)aString, aLength, aLBearing, aRBearing, aWidth, - aAscent, aDescent); -} - -// -// We save code space by merging the 8 and 16 bit text extents routines. -// The signature of this fuction is vague but that is okay since -// it is only used internally by nsXFontAAScaledBitmap and not -// presented as an API. -// -void -nsXFontAAScaledBitmap::TextExtents8or16(void *a8or16String, PRUint32 aLength, - PRInt32* aLBearing, PRInt32* aRBearing, - PRInt32* aWidth, PRInt32* aAscent, - PRInt32* aDescent) -{ - // make the indeterminate input variables determinate - const char *string8 = (const char *)a8or16String; - const XChar2b *string16 = (const XChar2b *)a8or16String; - - int dir, unscaled_ascent, unscaled_descent; - XCharStruct char_metrics; - int leftBearing = 0; - int rightBearing = 0; - int width = 0; - int ascent = 0; - int descent = 0; - - // initialize the values - if (aLength >= 1) { - if (mIsSingleByte) - XTextExtents(mUnscaledFontInfo, string8++, 1, - &dir, &unscaled_ascent, &unscaled_descent, &char_metrics); - else - XTextExtents16(mUnscaledFontInfo, string16++, 1, - &dir, &unscaled_ascent, &unscaled_descent, &char_metrics); - leftBearing = SCALED_SIZE(char_metrics.lbearing); - rightBearing = SCALED_SIZE(char_metrics.rbearing); - ascent = SCALED_SIZE(char_metrics.ascent); - descent = SCALED_SIZE(mUnscaledMax.ascent+char_metrics.descent) - - SCALED_SIZE(mUnscaledMax.ascent); - width = SCALED_SIZE(char_metrics.width); - } - - // - // Must go char by char to handle float->int rounding - // of the x position. If this is not done then when selecting - // (highlighting) text the selection x pos can differ - // which can make the text move around as more/less is selected - // - for (PRUint32 i=1; iReset(FreeGlyphHash, nsnull); - delete mGlyphHash; - } - if (mForegroundGC) { - XFreeGC(mDisplay, mForegroundGC); - } - if (mGdkFont) { - ::gdk_font_unref(mGdkFont); - } - if (mUnscaledBitmap) { - XFreePixmap(mDisplay, mUnscaledBitmap); - } -} - -// -// scale_image: -// -// Scale an image from a source area to a destination area -// using anti-aliasing. -// -// For performance reasons the scaling is done in 2 steps: -// horizontal scaling -// vertical scaling -// -// It is possible to do the scaling by expanding the souce -// into a a temporary buffer that is the Cartesian product of -// the source and destination. For a source image of Sw*Sh and a -// destination of Dw*Dh the temporary buffer is Tw=Sw*Dw wide and -// Th=Sh*Dh high; eg: for a 20x30 source expanding into a 30x45 it would -// use a temporary buffer of ((20*30) * (30*45)) bytes = 810k points. -// It takes (Sh*Dh)*(Sh*Dh) operation to expand into the the temp buffer -// and the same number to compress into the dest buffer for a total -// of 2*(Sh*Dh)*(Sh*Dh) operations (1.6 million for this example). -// -// If the expansion/compression is first done horizontally and *summed* -// into a temporary buffer that is the width of the destination and -// the height of the source it takes (Sw*Dw)*Sh operations. To -// expanded/compress the temp buffer into the destination takes -// Tw*(Th*Dh) = Dw*(Sh*Dh) operations. The total is now -// (Sw*Dw)*Sh + Dw*(Sh*Dh) (in this example (20*30)*30 + 30(30*45) = -// 18000 + 40500 = 58.5K operations or 3.7% of the Cartesian product). - - -// -// -static void -scale_image(nsAntiAliasedGlyph *aSrc, nsAntiAliasedGlyph *aDst) -{ - PRUint32 x, y, col; - PRUint8 buffer[65536]; - PRUint8 *horizontally_scaled_data = buffer; - PRUint8 *pHsd, *pDst; - PRUint32 dst_width = aDst->GetWidth(); - PRUint32 dst_buffer_width = aDst->GetBufferWidth(); - PRUint32 dst_height = aDst->GetHeight(); - PRUint8 *dst = aDst->GetBuffer(); - - if (aDst->GetBorder() != 0) { - NS_ASSERTION(aDst->GetBorder()!=0,"border not supported"); - return; - } - - PRUint32 ratio; - - PRUint8 *src = aSrc->GetBuffer(); - PRUint32 src_width = aSrc->GetWidth(); - NS_ASSERTION(src_width,"zero width glyph"); - if (src_width==0) - return; - - PRUint32 src_height = aSrc->GetHeight(); - NS_ASSERTION(src_height,"zero height glyph"); - if (src_height==0) - return; - - // - // scale the data horizontally - // - - // Calculate the ratio between the unscaled horizontal and - // the scaled horizontal. Use integer multiplication - // using a 24.8 format fixed decimal format. - ratio = (dst_width<<8)/src_width; - - PRUint32 hsd_len = dst_buffer_width * src_height; - // use the stack buffer if possible - if (hsd_len > sizeof(buffer)) { - horizontally_scaled_data = (PRUint8*)nsMemory::Alloc(hsd_len); - memset(horizontally_scaled_data, 0, hsd_len); - } - for (y=0; y<(dst_buffer_width*src_height); y++) - horizontally_scaled_data[y] = 0; - - pHsd = horizontally_scaled_data; - for (y=0; y>8] += (PRUint8)(((this_end-this_begin)*src_val)>>8); - } - DEBUG_DUMP((dump_byte_table(horizontally_scaled_data, - dst_width, src_height))); - } - } - - // - // Scale the data vertically - // - - // Calculate the ratio between the unscaled vertical and - // the scaled vertical. Use integer multiplication - // using a 24.8 format fixed decimal format. - ratio = (dst_height<<8)/src_height; - - for (x=0; x>8)*dst_buffer_width,col=(area_begin&0xffffff00); - col>8); - } - DEBUG_DUMP((dump_byte_table(dst, dst_width, dst_height))); - } - } - if (horizontally_scaled_data != buffer) - free(horizontally_scaled_data); -} - -// -// scale_imageAntiJag: -// -// Enlarge (scale) an image from a source area to a destination area -// using anti-aliasing. To smooth the edges the inside corners are -// fade-filled and the outside corners fade-cleared (anti jagged) -// -// anti-jagging example: -// -// - - - - - - - - -// |********| | *** | -// |********| | ****** | -// |********| |********| -// |********| -> | ********* -// |******** - - - - | ********* - - -// - - - -|********| - - -********* | -// |********| ******** | -// |********| | ****** | -// |********| | **** | -// - - - - - - - - -// -// Only fill-in/clear-out one half of the corner. For 45 degree -// lines this takes off the corners that stick out and fills in -// the inside corners. This should fill and clear about the same -// amount of pixels so the image should retain approximately the -// correct visual weight. -// -// This helps *a lot* with lines at 45 degree angles. -// This helps somewhat with lines at other angles. -// -// This fills in the corners of lines that cross making the -// image seem a bit heavier. -// -// To do the anti-jaggin the code needs to look a the pixels surrounding -// a pixel to see if the pixel is an inside corner or an outside -// corner. To avoid handling the pixels on the outer edge as special -// cases the image is padded. -// -// - -static void -scale_imageAntiJag(nsAntiAliasedGlyph *aSrc, nsAntiAliasedGlyph *aDst) -{ - PRUint32 x, y, col; - PRUint8 buffer[65536]; - PRUint8 *padded_src = aSrc->GetBuffer(); - PRUint8 exp_buffer[65536]; - PRUint8 *horizontally_scaled_data = buffer; - PRUint8 *pHsd, *pDst; - PRUint32 dst_width = aDst->GetWidth(); - PRUint32 dst_buffer_width = aDst->GetBufferWidth(); - PRUint32 dst_height = aDst->GetHeight(); - PRUint8 *dst = aDst->GetBuffer(); - - if (aDst->GetBorder() != 0) { - NS_ASSERTION(aDst->GetBorder()==0, "non zero dest border not supported"); - return; - } - PRUint32 expand = (((dst_width<<8)/aSrc->GetWidth())+255)>>8; - - PRUint32 src_width = aSrc->GetWidth(); - PRUint32 src_height = aSrc->GetHeight(); - PRUint32 border_width = aSrc->GetBorder(); - PRUint32 padded_width = aSrc->GetWidth() + (2*border_width); - PRUint32 padded_height = aSrc->GetHeight() + (2*border_width); - - // - // Expand the data (anti-jagging comes later) - // - PRUint32 expanded_width = padded_width * expand; - PRUint32 expanded_height = padded_height * expand; - - PRUint32 start_x = border_width * expand; - PRUint32 start_y = border_width * expand; - - PRUint8 *expanded_data = exp_buffer; - PRUint32 exp_len = expanded_width*expanded_height; - if (exp_len > sizeof(exp_buffer)) - expanded_data = (PRUint8*)malloc(expanded_width*expanded_height); - for (y=0; y> 8) - // - // Note: this code only works for black (0) and white (255) values - // - DEBUG_DUMP((dump_byte_table(expanded_data, expanded_width,expanded_height))); - PRUint8 *ps, *es; - PRUint32 jag_len = (expand)/2; // fill/clear one half of the corner - PRUint32 i, j; - for (y=0; y>8); - } - if ((SRC_DOWN(ps)==255) && (SRC_LEFT(ps)==255)) { - // triangular fade fill - for (i=0; i>8); - } - if ((SRC_LEFT(ps)==255) && (SRC_UP(ps)==255)) { - // triangular fade fill - for (i=0; i>8); - } - if ((SRC_UP(ps)==255) && (SRC_RIGHT(ps)==255)) { - // triangular fade fill - for (i=0; i>8); - } - } - // - // Round off the outside of corners - else { - jag_len = ((expand+1)/2); - if ((SRC_UP_LEFT(ps)==0) && (SRC_UP(ps)==0) && (SRC_LEFT(ps)==0)) { - // triangular fade clear - for (i=0; i>8); - } - if ((SRC_UP(ps)==0) && (SRC_UP_RIGHT(ps)==0) && (SRC_RIGHT(ps)==0)) { - // triangular fade clear - for (i=0; i>8); - } - if ((SRC_LEFT(ps)==0) && (SRC_DOWN_LEFT(ps)==0) && (SRC_DOWN(ps)==0)) { - // triangular fade clear - for (i=0; i>8); - } - if ((SRC_RIGHT(ps)==0) && (SRC_DOWN_RIGHT(ps)==0) && (SRC_DOWN(ps)==0)){ - // triangular fade clear - for (i=0; i>8); - } - } - } - } - DEBUG_DUMP((dump_byte_table(expanded_data, expanded_width,expanded_height))); - - // - // scale the data horizontally - // - // note: size is +dst_buffer_width because the loop can go one pixel - // (horizontal or vertical) past array (with a near 0 width area) - PRUint32 ratio = ((dst_width<<8)/expand)/src_width; - - PRUint32 hsd_len = (dst_buffer_width+1) * expanded_height; - if (hsd_len > sizeof(buffer)) { - horizontally_scaled_data = (PRUint8*)nsMemory::Alloc(hsd_len); - memset(horizontally_scaled_data, 0, hsd_len); - } - for (i=0; i>8] += (PRUint8)(((this_end-this_begin)*src_val)>>8); - if ((&pHsd[col>>8]-horizontally_scaled_data) > (int)hsd_len) { - NS_ASSERTION(0, "buffer too small"); - return; - } - } - } - - DEBUG_DUMP((dump_byte_table(horizontally_scaled_data, - dst_width, expanded_height))); - } - - // - // scale the data vertically - // - ratio = ((dst_height<<8)/expand)/src_height; - PRUint32 len_y = src_height * expand; - for (x=0; x>8)*dst_buffer_width,col=(area_begin&0xffffff00); - col>8); - pDst[c] += val; - } - } - DEBUG_DUMP((dump_byte_table(dst, dst_width, dst_height))); - } - if (expanded_data != exp_buffer) - free(expanded_data); - if (horizontally_scaled_data != buffer) - free(horizontally_scaled_data); -} - -#ifdef DEBUG -void -nsXFontAAScaledBitmap::dump_XImage_blue_data(XImage *ximage) -{ - int x, y; - int width = ximage->width; - int height = ximage->height; - int pitch = ximage->bytes_per_line; - int depth = DefaultDepth(sDisplay, DefaultScreen(sDisplay)); - PRUint8 *lineStart = (PRUint8 *)ximage->data; - printf("dump_byte_table: width=%d, height=%d\n", width, height); - printf(" "); - for (x=0; (xdata; - for (y=0; ybytes_per_line; - } - } - else if ((depth == 24) || (depth == 32)) { - long *data = (long *)ximage->data; - for (y=0; y=aMinValue) - val += (int)rint((double)(i-aMinValue)*aGain); - val = MAX(0, val); - val = MIN(val, 255); - aTable[i] = (PRUint8)val; - } -} - diff --git a/gfx/src/x11shared/nsXFontAAScaledBitmap.h b/gfx/src/x11shared/nsXFontAAScaledBitmap.h deleted file mode 100644 index a0204ceae158..000000000000 --- a/gfx/src/x11shared/nsXFontAAScaledBitmap.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsXFontAAScaledBitmap_h__ -#define nsXFontAAScaledBitmap_h__ - -#include -#include - -#include -#include "nspr.h" -#include "nsXFont.h" -#include "nsAntiAliasedGlyph.h" - -extern PRUint8 gAASBDarkTextMinValue; -extern double gAASBDarkTextGain; -extern PRUint8 gAASBLightTextMinValue; -extern double gAASBLightTextGain; - - -#define SCALED_SIZE(x) (PRInt32)(rint(((double)(x))*mRatio)) -class nsHashtable; - -class nsXFontAAScaledBitmap : public nsXFont { -public: - // we use PRUint16 instead of PRUint32 for the final two arguments in this - // constructor to work around a GCC 2.95[.3] bug which would otherwise cause - // these parameters to be corrupted in the callee. n.b. at the time of - // writing the only caller is passing PRUint16 values anyway (and within - // the constructor we go on toassign a parameter to a PRUint16-sized member - // variable) so semantically nothing is lost. - nsXFontAAScaledBitmap(Display *aDisplay, int aScreen, GdkFont *, - PRUint16, PRUint16); - ~nsXFontAAScaledBitmap(); - - void DrawText8(GdkDrawable *Drawable, GdkGC *GC, PRInt32, PRInt32, - const char *, PRUint32); - void DrawText16(GdkDrawable *Drawable, GdkGC *GC, PRInt32, PRInt32, - const XChar2b *, PRUint32); - PRBool GetXFontProperty(Atom, unsigned long *); - XFontStruct *GetXFontStruct(); - PRBool LoadFont(); - void TextExtents8(const char *, PRUint32, PRInt32*, PRInt32*, - PRInt32*, PRInt32*, PRInt32*); - void TextExtents16(const XChar2b *, PRUint32, PRInt32*, PRInt32*, - PRInt32*, PRInt32*, PRInt32*); - PRInt32 TextWidth8(const char *, PRUint32); - PRInt32 TextWidth16(const XChar2b *, PRUint32); - void UnloadFont(); - -public: - static PRBool InitGlobals(Display *aDisplay, int aScreen); - static void FreeGlobals(); - -protected: - void DrawText8or16(GdkDrawable *Drawable, GdkGC *GC, PRInt32, - PRInt32, void *, PRUint32); - void TextExtents8or16(void *, PRUint32, PRInt32*, PRInt32*, - PRInt32*, PRInt32*, PRInt32*); - PRBool GetScaledGreyImage(const char *, nsAntiAliasedGlyph **); -#ifdef DEBUG - void dump_XImage_blue_data(XImage *ximage); -#endif - static PRBool DisplayIsLocal(Display *); - -protected: - PRBool mAlreadyLoaded; - Display *mDisplay; - GC mForegroundGC; - GdkFont *mGdkFont; - nsHashtable* mGlyphHash; - double mRatio; - XFontStruct mScaledFontInfo; - GlyphMetrics mScaledMax; - int mScreen; - Pixmap mUnscaledBitmap; - XFontStruct *mUnscaledFontInfo; - GlyphMetrics mUnscaledMax; - PRUint16 mUnscaledSize; - -// class globals -protected: - static Display *sDisplay; - static GC sBackgroundGC; // used to clear the pixmaps - // before drawing the glyph - static PRUint8 sWeightedScaleDarkText[256]; - static PRUint8 sWeightedScaleLightText[256]; -}; - -#endif /* nsXFontAAScaledBitmap_h__ */ diff --git a/gfx/src/x11shared/nsXFontNormal.cpp b/gfx/src/x11shared/nsXFontNormal.cpp deleted file mode 100644 index a3c6527a269d..000000000000 --- a/gfx/src/x11shared/nsXFontNormal.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "gfx-config.h" -#include "nscore.h" -#include "nsXFontNormal.h" -#include "nsRenderingContextGTK.h" -#include "nsGdkUtils.h" - -void -nsXFontNormal::DrawText8(GdkDrawable *aDrawable, GdkGC *aGC, - PRInt32 aX, PRInt32 aY, - const char *aString, PRUint32 aLength) -{ - my_gdk_draw_text(aDrawable, mGdkFont, aGC, aX, aY, aString, aLength); -} - -void -nsXFontNormal::DrawText16(GdkDrawable *aDrawable, GdkGC *aGC, - PRInt32 aX, PRInt32 aY, - const XChar2b *aString, PRUint32 aLength) -{ - my_gdk_draw_text(aDrawable, mGdkFont, aGC, aX, aY, - (const char *)aString, aLength*2); -} - -PRBool -nsXFontNormal::GetXFontProperty(Atom aAtom, unsigned long *aValue) -{ - NS_ASSERTION(mGdkFont, "GetXFontProperty called before font loaded"); - if (mGdkFont==nsnull) - return PR_FALSE; - - XFontStruct *fontInfo = (XFontStruct *)GDK_FONT_XFONT(mGdkFont); - - return ::XGetFontProperty(fontInfo, aAtom, aValue); -} - -XFontStruct * -nsXFontNormal::GetXFontStruct() -{ - NS_ASSERTION(mGdkFont, "GetXFontStruct called before font loaded"); - if (mGdkFont==nsnull) - return nsnull; - - return (XFontStruct *)GDK_FONT_XFONT(mGdkFont); -} - -PRBool -nsXFontNormal::LoadFont() -{ - if (!mGdkFont) - return PR_FALSE; - XFontStruct *fontInfo = (XFontStruct *)GDK_FONT_XFONT(mGdkFont); - mIsSingleByte = (fontInfo->min_byte1 == 0) && (fontInfo->max_byte1 == 0); - return PR_TRUE; -} - -nsXFontNormal::nsXFontNormal(GdkFont *aGdkFont) -{ - mGdkFont = ::gdk_font_ref(aGdkFont); -} - -void -nsXFontNormal::TextExtents8(const char *aString, PRUint32 aLength, - PRInt32* aLBearing, PRInt32* aRBearing, - PRInt32* aWidth, PRInt32* aAscent, - PRInt32* aDescent) -{ - gdk_text_extents(mGdkFont, aString, aLength, - aLBearing, aRBearing, aWidth, aAscent, aDescent); -} - -void -nsXFontNormal::TextExtents16(const XChar2b *aString, PRUint32 aLength, - PRInt32* aLBearing, PRInt32* aRBearing, - PRInt32* aWidth, PRInt32* aAscent, - PRInt32* aDescent) -{ - gdk_text_extents(mGdkFont, (const char *)aString, aLength*2, - aLBearing, aRBearing, aWidth, aAscent, aDescent); -} - -PRInt32 -nsXFontNormal::TextWidth8(const char *aString, PRUint32 aLength) -{ - NS_ASSERTION(mGdkFont, "TextWidth8 called before font loaded"); - if (mGdkFont==nsnull) - return 0; - PRInt32 width = gdk_text_width(mGdkFont, aString, aLength); - return width; -} - -PRInt32 -nsXFontNormal::TextWidth16(const XChar2b *aString, PRUint32 aLength) -{ - NS_ASSERTION(mGdkFont, "TextWidth16 called before font loaded"); - if (mGdkFont==nsnull) - return 0; - PRInt32 width = gdk_text_width(mGdkFont, (const char *)aString, aLength*2); - return width; -} - -void -nsXFontNormal::UnloadFont() -{ - delete this; -} - -nsXFontNormal::~nsXFontNormal() -{ - if (mGdkFont) { - ::gdk_font_unref(mGdkFont); - } -} - diff --git a/gfx/src/x11shared/nsXFontNormal.h b/gfx/src/x11shared/nsXFontNormal.h deleted file mode 100644 index 297d57337c82..000000000000 --- a/gfx/src/x11shared/nsXFontNormal.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Stell - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef nsXFontNormal_h__ -#define nsXFontNormal_h__ - -#include -#include - -#include -#include "nspr.h" -#include "nsXFont.h" - -class nsXFontNormal : public nsXFont { -public: - nsXFontNormal(GdkFont *); - ~nsXFontNormal(); - - void DrawText8(GdkDrawable *Drawable, GdkGC *GC, PRInt32, PRInt32, - const char *, PRUint32); - void DrawText16(GdkDrawable *Drawable, GdkGC *GC, PRInt32, PRInt32, - const XChar2b *, PRUint32); - PRBool GetXFontProperty(Atom, unsigned long *); - XFontStruct *GetXFontStruct(); - PRBool LoadFont(); - void TextExtents8(const char *, PRUint32, PRInt32*, PRInt32*, - PRInt32*, PRInt32*, PRInt32*); - void TextExtents16(const XChar2b *, PRUint32, PRInt32*, PRInt32*, - PRInt32*, PRInt32*, PRInt32*); - PRInt32 TextWidth8(const char *, PRUint32); - PRInt32 TextWidth16(const XChar2b *, PRUint32); - void UnloadFont(); -protected: - GdkFont *mGdkFont; -}; - -#endif /* nsXFontNormal_h__ */ diff --git a/toolkit/library/libxul-config.mk b/toolkit/library/libxul-config.mk index 5851ebc8adab..cbd1218489a3 100644 --- a/toolkit/library/libxul-config.mk +++ b/toolkit/library/libxul-config.mk @@ -276,9 +276,6 @@ else # Platform-specific GFX layer ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) COMPONENT_LIBS += gfx_mac endif - ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT))) - COMPONENT_LIBS += gfx_gtk - endif ifdef MOZ_ENABLE_PHOTON COMPONENT_LIBS += gfx_photon endif diff --git a/toolkit/library/nsStaticXULComponents.cpp b/toolkit/library/nsStaticXULComponents.cpp index 9b84e9038e49..82e80ca78956 100644 --- a/toolkit/library/nsStaticXULComponents.cpp +++ b/toolkit/library/nsStaticXULComponents.cpp @@ -82,9 +82,7 @@ #ifdef MOZ_CAIRO_GFX # define GFX_MODULES MODULE(nsGfxModule) #else -# if defined(MOZ_WIDGET_GTK2) -# define GFX_MODULES MODULE(nsGfxGTKModule) -# elif defined(MOZ_WIDGET_PHOTON) +# if defined(MOZ_WIDGET_PHOTON) # define GFX_MODULES MODULE(nsGfxPhModule) # elif defined(XP_WIN) # define GFX_MODULES MODULE(nsGfxModule) diff --git a/widget/src/gtk2/Makefile.in b/widget/src/gtk2/Makefile.in index ddf2eb8777f8..149bf4f0ab75 100644 --- a/widget/src/gtk2/Makefile.in +++ b/widget/src/gtk2/Makefile.in @@ -69,15 +69,13 @@ REQUIRES = xpcom \ layout \ util \ locale \ + thebes \ + cairo \ $(NULL) -ifeq ($(MOZ_ENABLE_CAIRO_GFX),1) -REQUIRES += thebes cairo - ifeq ($(MOZ_ENABLE_GLITZ),1) REQUIRES += glitz glitzglx endif -endif CSRCS = \ mozcontainer.c \ @@ -130,11 +128,9 @@ EXTRA_DSO_LDOPTS += \ $(MOZ_STARTUP_NOTIFICATION_LIBS) \ $(XLDFLAGS) \ $(XLIBS) \ - $(MOZ_GTK2_LIBS) - -ifeq ($(MOZ_ENABLE_CAIRO_GFX),1) -EXTRA_DSO_LDOPTS += -lthebes -endif + $(MOZ_GTK2_LIBS) \ + -lthebes \ + $(NULL) EXPORTS = \ nsIGdkPixbufImage.h \ @@ -156,10 +152,7 @@ CFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_STARTUP_NOTIFICATION_CFLAGS) CXXFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_STARTUP_NOTIFICATION_CFLAGS) DEFINES += -DUSE_XIM - -ifdef MOZ_ENABLE_CAIRO_GFX DEFINES += -DCAIRO_GFX -endif ifdef MOZ_ENABLE_POSTSCRIPT DEFINES += -DUSE_POSTSCRIPT diff --git a/widget/src/gtk2/nsDeviceContextSpecG.cpp b/widget/src/gtk2/nsDeviceContextSpecG.cpp index 7410e66d16c6..085270ab514d 100644 --- a/widget/src/gtk2/nsDeviceContextSpecG.cpp +++ b/widget/src/gtk2/nsDeviceContextSpecG.cpp @@ -390,22 +390,9 @@ nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK() delete mPrintJob; } -#ifdef MOZ_CAIRO_GFX NS_IMPL_ISUPPORTS1(nsDeviceContextSpecGTK, nsIDeviceContextSpec) -#else -/* Use only PostScript module */ -#if defined(USE_POSTSCRIPT) -NS_IMPL_ISUPPORTS2(nsDeviceContextSpecGTK, - nsIDeviceContextSpec, - nsIDeviceContextSpecPS) -#else -NS_IMPL_ISUPPORTS1(nsDeviceContextSpecGTK, - nsIDeviceContextSpec) -#endif -#endif -#ifdef MOZ_CAIRO_GFX //#define USE_PDF 1 #include "gfxPDFSurface.h" #include "gfxPSSurface.h" @@ -447,7 +434,6 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurfac return NS_OK; } -#endif /** ------------------------------------------------------- * Initialize the nsDeviceContextSpecGTK diff --git a/widget/src/gtk2/nsDeviceContextSpecG.h b/widget/src/gtk2/nsDeviceContextSpecG.h index 5df81fb02426..7ec6972596f4 100644 --- a/widget/src/gtk2/nsDeviceContextSpecG.h +++ b/widget/src/gtk2/nsDeviceContextSpecG.h @@ -45,12 +45,6 @@ #include "nsVoidArray.h" #include "nsCOMPtr.h" -#ifndef MOZ_CAIRO_GFX -#ifdef USE_POSTSCRIPT -#include "nsIDeviceContextSpecPS.h" -#endif /* USE_POSTSCRIPT */ -#endif - #include "nsCRT.h" /* should be ? */ #include "nsIPrintJobGTK.h" @@ -65,20 +59,13 @@ typedef enum } PrintMethod; class nsDeviceContextSpecGTK : public nsIDeviceContextSpec -#ifndef MOZ_CAIRO_GFX -#ifdef USE_POSTSCRIPT - , public nsIDeviceContextSpecPS -#endif /* USE_POSTSCRIPT */ -#endif { public: nsDeviceContextSpecGTK(); NS_DECL_ISUPPORTS -#ifdef MOZ_CAIRO_GFX NS_IMETHOD GetSurfaceForPrinter(gfxASurface **surface); -#endif NS_IMETHOD Init(nsIWidget *aWidget, nsIPrintSettings* aPS, PRBool aIsPrintPreview); NS_IMETHOD ClosePrintManager(); diff --git a/widget/src/gtk2/nsDragService.cpp b/widget/src/gtk2/nsDragService.cpp index abb383971723..7197b1bdcd7e 100644 --- a/widget/src/gtk2/nsDragService.cpp +++ b/widget/src/gtk2/nsDragService.cpp @@ -58,10 +58,8 @@ #include #include "nsCRT.h" -#ifdef MOZ_CAIRO_GFX #include "gfxASurface.h" #include "nsImageToPixbuf.h" -#endif static PRLogModuleInfo *sDragLm = NULL; @@ -203,7 +201,6 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, 1, &event); -#ifdef MOZ_CAIRO_GFX GdkPixbuf* dragPixbuf = nsnull; nsRect dragRect; if (mHasImage || mSelection) { @@ -222,10 +219,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, mScreenY - NSToIntRound(dragRect.y)); else gtk_drag_set_icon_default(context); -#else - // use a default icon - gtk_drag_set_icon_default(context); -#endif + gtk_target_list_unref(sourceList); } diff --git a/widget/src/gtk2/nsImageToPixbuf.cpp b/widget/src/gtk2/nsImageToPixbuf.cpp index 25886ee19cd6..fc261d69a2d7 100644 --- a/widget/src/gtk2/nsImageToPixbuf.cpp +++ b/widget/src/gtk2/nsImageToPixbuf.cpp @@ -37,11 +37,9 @@ #include -#ifdef MOZ_CAIRO_GFX #include "gfxASurface.h" #include "gfxImageSurface.h" #include "gfxContext.h" -#endif #include "nsIGdkPixbufImage.h" @@ -70,7 +68,6 @@ nsImageToPixbuf::ConvertImageToPixbuf(nsIImage* aImage) GdkPixbuf* nsImageToPixbuf::ImageToPixbuf(nsIImage* aImage) { -#ifdef MOZ_CAIRO_GFX PRInt32 width = aImage->GetWidth(), height = aImage->GetHeight(); @@ -78,15 +75,8 @@ nsImageToPixbuf::ImageToPixbuf(nsIImage* aImage) aImage->GetSurface(getter_AddRefs(surface)); return SurfaceToPixbuf(surface, width, height); -#else - nsCOMPtr img(do_QueryInterface(aImage)); - if (img) - return img->GetGdkPixbuf(); - return NULL; -#endif } -#ifdef MOZ_CAIRO_GFX GdkPixbuf* nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32 aHeight) { @@ -162,4 +152,3 @@ nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32 return pixbuf; } -#endif diff --git a/widget/src/gtk2/nsImageToPixbuf.h b/widget/src/gtk2/nsImageToPixbuf.h index dbc6cb977453..e861f83f4c9d 100644 --- a/widget/src/gtk2/nsImageToPixbuf.h +++ b/widget/src/gtk2/nsImageToPixbuf.h @@ -50,10 +50,8 @@ class nsImageToPixbuf : public nsIImageToPixbuf { // Friendlier version of ConvertImageToPixbuf for callers inside of // widget static GdkPixbuf* ImageToPixbuf(nsIImage* aImage); -#ifdef MOZ_CAIRO_GFX static GdkPixbuf* SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32 aHeight); -#endif private: ~nsImageToPixbuf() {} }; diff --git a/widget/src/gtk2/nsNativeThemeGTK.cpp b/widget/src/gtk2/nsNativeThemeGTK.cpp index 3a42b1ec447c..5982ce0be6b1 100644 --- a/widget/src/gtk2/nsNativeThemeGTK.cpp +++ b/widget/src/gtk2/nsNativeThemeGTK.cpp @@ -63,11 +63,9 @@ #include #include -#ifdef MOZ_CAIRO_GFX #include "gfxContext.h" #include "gfxPlatformGtk.h" #include "gfxXlibNativeRenderer.h" -#endif NS_IMPL_ISUPPORTS2(nsNativeThemeGTK, nsITheme, nsIObserver) @@ -463,7 +461,6 @@ NativeThemeErrorHandler(Display* dpy, XErrorEvent* error) { return 0; } -#ifdef MOZ_CAIRO_GFX class ThemeRenderer : public gfxXlibNativeRenderer { public: ThemeRenderer(GtkWidgetState aState, GtkThemeWidgetType aGTKWidgetType, @@ -525,7 +522,6 @@ ThemeRenderer::NativeDraw(Display* dpy, Drawable drawable, Visual* visual, g_object_unref(G_OBJECT(gdkPixmap)); return NS_OK; } -#endif static PRBool GetExtraSizeForWidget(PRUint8 aWidgetType, nsIntMargin* aExtra) @@ -571,55 +567,6 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext, &flags)) return NS_OK; -#ifndef MOZ_CAIRO_GFX - GdkWindow* window = NS_STATIC_CAST(GdkWindow*, - aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_GDK_DRAWABLE)); - - nsTransform2D* transformMatrix; - aContext->GetCurrentTransform(transformMatrix); - - nsRect tr(aRect); - transformMatrix->TransformCoord(&tr.x, &tr.y, &tr.width, &tr.height); - GdkRectangle gdk_rect = {tr.x, tr.y, tr.width, tr.height}; - - nsRect cr(aClipRect); - transformMatrix->TransformCoord(&cr.x, &cr.y, &cr.width, &cr.height); - GdkRectangle gdk_clip = {cr.x, cr.y, cr.width, cr.height}; - - NS_ASSERTION(!IsWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType), - "Trying to render an unsafe widget!"); - - PRBool safeState = IsWidgetStateSafe(mSafeWidgetStates, aWidgetType, &state); - XErrorHandler oldHandler = nsnull; - if (!safeState) { - gLastXError = 0; - oldHandler = XSetErrorHandler(NativeThemeErrorHandler); - } - - moz_gtk_widget_paint(gtkWidgetType, window, &gdk_rect, &gdk_clip, &state, - flags); - - if (!safeState) { - gdk_flush(); - XSetErrorHandler(oldHandler); - - if (gLastXError) { -#ifdef DEBUG - printf("GTK theme failed for widget type %d, error was %d, state was " - "[active=%d,focused=%d,inHover=%d,disabled=%d]\n", - aWidgetType, gLastXError, state.active, state.focused, - state.inHover, state.disabled); -#endif - NS_WARNING("GTK theme failed; disabling unsafe widget"); - SetWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType); - // force refresh of the window, because the widget was not - // successfully drawn it must be redrawn using the default look - RefreshWidgetWindow(aFrame); - } else { - SetWidgetStateSafe(mSafeWidgetStates, aWidgetType, &state); - } - } -#else nsCOMPtr dctx = nsnull; aContext->GetDeviceContext(*getter_AddRefs(dctx)); PRInt32 p2a = dctx->AppUnitsPerDevPixel(); @@ -706,7 +653,6 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext, SetWidgetStateSafe(mSafeWidgetStates, aWidgetType, &state); } } -#endif return NS_OK; } diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp index b681d8f5da0d..f307ca7610b4 100644 --- a/widget/src/gtk2/nsWindow.cpp +++ b/widget/src/gtk2/nsWindow.cpp @@ -104,7 +104,6 @@ static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility" #include "nsIInterfaceRequestorUtils.h" #include "nsAutoPtr.h" -#ifdef MOZ_CAIRO_GFX #include "gfxPlatformGtk.h" #include "gfxXlibSurface.h" #include "gfxContext.h" @@ -114,7 +113,6 @@ static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility" #include "gfxGlitzSurface.h" #include "glitz-glx.h" #endif -#endif /* For PrepareNativeWidget */ static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID); @@ -464,11 +462,9 @@ nsWindow::Destroy(void) // window this isn't going to harm anything. mWindowGroup = nsnull; -#ifdef MOZ_CAIRO_GFX // Destroy thebes surface now. Badness can happen if we destroy // the surface after its X Window. mThebesSurface = nsnull; -#endif if (mDragMotionTimerID) { gtk_timeout_remove(mDragMotionTimerID); @@ -1652,7 +1648,6 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent) nsCOMPtr rc = getter_AddRefs(GetRenderingContext()); -#ifdef MOZ_CAIRO_GFX PRBool translucent; GetWindowTranslucency(translucent); nsIntRect boundsRect; @@ -1722,16 +1717,17 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent) } #endif // MOZ_ENABLE_GLITZ } -#endif // MOZ_CAIRO_GFX +#if 0 // NOTE: Paint flashing region would be wrong for cairo, since // cairo inflates the update region, etc. So don't paint flash // for cairo. -#if !defined(MOZ_CAIRO_GFX) && defined(DEBUG) +#ifdef DEBUG if (WANT_PAINT_FLASHING && aEvent->window) gdk_window_flash(aEvent->window, 1, 100, aEvent->region); -#endif // !defined(MOZ_CAIRO_GFX) && defined(DEBUG) - +#endif +#endif + nsPaintEvent event(PR_TRUE, NS_PAINT, this); event.refPoint.x = aEvent->area.x; event.refPoint.y = aEvent->area.y; @@ -1745,8 +1741,6 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent) // DispatchEvent can Destroy us (bug 378273), avoid doing any paint // operations below if that happened - it will lead to XError and exit(). if (NS_LIKELY(!mIsDestroyed)) { - -#ifdef MOZ_CAIRO_GFX if (status != nsEventStatus_eIgnore) { if (translucent) { nsRefPtr pattern = ctx->PopGroup(); @@ -1794,8 +1788,6 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent) } ctx->Restore(); -#endif // MOZ_CAIRO_GFX - } g_free(rects); @@ -5728,7 +5720,6 @@ IM_get_input_context(nsWindow *aWindow) #endif -#ifdef MOZ_CAIRO_GFX // return the gfxASurface for rendering to this widget gfxASurface* nsWindow::GetThebesSurface() @@ -5791,4 +5782,3 @@ nsWindow::GetThebesSurface() return mThebesSurface; } -#endif diff --git a/widget/src/gtk2/nsWindow.h b/widget/src/gtk2/nsWindow.h index d3f53cbd4f9b..999ce711edc9 100644 --- a/widget/src/gtk2/nsWindow.h +++ b/widget/src/gtk2/nsWindow.h @@ -350,9 +350,7 @@ class nsWindow : public nsCommonWidget, public nsSupportsWeakReference NS_IMETHOD UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas); #endif -#ifdef MOZ_CAIRO_GFX gfxASurface *GetThebesSurface(); -#endif #ifdef ACCESSIBILITY static PRBool sAccessibilityEnabled; @@ -386,9 +384,7 @@ class nsWindow : public nsCommonWidget, public nsSupportsWeakReference PRUint32 mTransparencyBitmapWidth; PRUint32 mTransparencyBitmapHeight; -#ifdef MOZ_CAIRO_GFX nsRefPtr mThebesSurface; -#endif #ifdef ACCESSIBILITY nsCOMPtr mRootAccessible; diff --git a/xpinstall/packager/packages-unix b/xpinstall/packager/packages-unix index 06a2ceeaee88..021c88f9f08e 100644 --- a/xpinstall/packager/packages-unix +++ b/xpinstall/packager/packages-unix @@ -93,7 +93,7 @@ bin/xpicleanup bin/res/cmessage.txt ; this is used by gtk embedding clients bin/libgtkembedmoz.so -; This is used by libgfxps and libgfx_gtk +; This is used by libgfxps bin/libgfxpsshar.so bin/components/alerts.xpt bin/components/libaccessibility.so @@ -159,7 +159,6 @@ bin/components/composer.xpt bin/components/libdocshell.so bin/components/libeditor.so bin/components/libembedcomponents.so -bin/components/libgfx_gtk.so bin/components/libgfxps.so bin/components/libgfxxprint.so bin/components/libimglib2.so