cairo landing: land thebes
This commit is contained in:
Родитель
85e103d8ae
Коммит
8603ea4fbf
|
@ -89,7 +89,7 @@ DIRS += xprintutil xprint
|
|||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_CAIRO_GFX
|
||||
DIRS += cairo
|
||||
DIRS += thebes
|
||||
else
|
||||
ifdef MOZ_ENABLE_GTK
|
||||
DIRS += gtk
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
# ***** 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 thebes gfx
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# mozilla.org.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Vladimir Vukicevic <vladimir@pobox.com>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = gfx
|
||||
LIBRARY_NAME = gkgfxthebes
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = nsGfxModule
|
||||
GRE_MODULE = 1
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
cairo \
|
||||
libpixman \
|
||||
glitz \
|
||||
thebes \
|
||||
gfx \
|
||||
widget \
|
||||
intl \
|
||||
view \
|
||||
pref \
|
||||
uconv \
|
||||
unicharutil \
|
||||
locale \
|
||||
necko \
|
||||
content \
|
||||
layout \
|
||||
dom \
|
||||
debug \
|
||||
imglib2 \
|
||||
$(ZLIB_REQUIRES) \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsThebesDeviceContext.cpp \
|
||||
nsThebesDrawingSurface.cpp \
|
||||
nsThebesImage.cpp \
|
||||
nsThebesRegion.cpp \
|
||||
nsThebesBlender.cpp \
|
||||
nsThebesGfxFactory.cpp \
|
||||
nsThebesRenderingContext.cpp \
|
||||
nsThebesScreen.cpp \
|
||||
nsThebesScreenManager.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)mozutil_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gfxshared_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)mozcairo.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)mozlibpixman.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)thebes.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_GLITZ
|
||||
SHARED_LIBRARY_LIBS += $(DIST)/lib/$(LIB_PREFIX)mozglitz.$(LIB_SUFFIX)
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LIBS = gkgfx
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
CPPSRCS += nsSystemFontsGTK2.cpp
|
||||
|
||||
ifdef MOZ_ENABLE_PANGO
|
||||
CPPSRCS += nsFontMetricsPango.cpp \
|
||||
mozilla-decoder.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_GLITZ
|
||||
SHARED_LIBRARY_LIBS += $(DIST)/lib/$(LIB_PREFIX)mozglitzglx.$(LIB_SUFFIX)
|
||||
REQUIRES += glitzglx
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
CPPSRCS += nsFontMetricsWin2.cpp \
|
||||
nsSystemFontsWin.cpp \
|
||||
$(NULL)
|
||||
REQUIRES += glitzwgl
|
||||
|
||||
_OS_LIBS = usp10
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,$(_OS_LIBS))
|
||||
endif
|
||||
|
||||
EXPORTS += nsIThebesRenderingContext.h
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/. \
|
||||
-I$(srcdir)/.. \
|
||||
-I$(srcdir)/../shared \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(TK_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
CFLAGS += $(TK_CFLAGS)
|
||||
|
||||
ifdef MOZ_ENABLE_GTK2
|
||||
DEFINES += -DMOZ_ENABLE_GTK2
|
||||
endif
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
/* -*- 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
|
||||
* <blizzard@mozilla.org>. 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 <pango/pangoxft.h>
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
#include <pango/pangofc-font.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#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<nsIUnicodeEncoder> 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;
|
||||
|
||||
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<nsIPersistentProperties> props;
|
||||
nsCOMPtr<nsISimpleEnumerator> 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<nsIPropertyElement> 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(pango_xft_get_font_map(GDK_DISPLAY(),gdk_x11_get_default_screen())),
|
||||
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<nsIUnicodeEncoder> encoder;
|
||||
nsCOMPtr<nsICharRepresentable> 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);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/* -*- 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
|
||||
* <blizzard@mozilla.org>. 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 <pango/pangofc-decoder.h>
|
||||
|
||||
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 */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,829 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
*
|
||||
* 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 "nsFontMetricsWin2.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsAutoBuffer.h"
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <Usp10.h>
|
||||
|
||||
#include "cairo-win32.h"
|
||||
|
||||
|
||||
// for using the cairo apis for fonts...
|
||||
#define USE_SCALED_FONTS
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsFontMetricsWin, nsIFontMetrics)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
nsFontMetricsWin::nsFontMetricsWin()
|
||||
{
|
||||
_putenv("XPCOM_DEBUG_BREAK=warn");
|
||||
}
|
||||
|
||||
nsFontMetricsWin::~nsFontMetricsWin()
|
||||
{
|
||||
cairo_font_face_destroy(mCairoFontFace);
|
||||
cairo_scaled_font_destroy(mCairoFont);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
{
|
||||
nsFontMetricsWin* metrics = (nsFontMetricsWin*) aData;
|
||||
metrics->mFonts.AppendString(aFamily);
|
||||
if (aGeneric) {
|
||||
metrics->mGeneric.Assign(aFamily);
|
||||
//ToLowerCase(metrics->mGeneric);
|
||||
return PR_FALSE; // stop
|
||||
}
|
||||
++metrics->mGenericIndex;
|
||||
|
||||
return PR_TRUE; // don't stop
|
||||
}
|
||||
|
||||
cairo_font_face_t *
|
||||
nsFontMetricsWin::MakeCairoFontFace(const nsString *aFontName)
|
||||
{
|
||||
cairo_font_face_t *fontFace = nsnull;
|
||||
|
||||
LOGFONTW logFont;
|
||||
memset(&logFont, 0, sizeof(LOGFONTW));
|
||||
FillLogFont(&logFont, aFontName);
|
||||
|
||||
fontFace = cairo_win32_font_face_create_for_logfontw(&logFont);
|
||||
|
||||
return fontFace;
|
||||
}
|
||||
cairo_scaled_font_t *
|
||||
nsFontMetricsWin::MakeCairoScaledFont(cairo_t *cr, cairo_font_face_t *aFontFace)
|
||||
{
|
||||
cairo_scaled_font_t *font = nsnull;
|
||||
|
||||
float app2dev = mDeviceContext->AppUnitsToDevUnits();
|
||||
double size = NSToIntRound(mFont.size * app2dev);
|
||||
cairo_matrix_t sizeMatrix, ctm;
|
||||
if (cr)
|
||||
cairo_get_matrix(cr, &ctm);
|
||||
else
|
||||
cairo_matrix_init_identity(&ctm);
|
||||
|
||||
cairo_matrix_init_scale(&sizeMatrix, size, size);
|
||||
|
||||
cairo_font_options_t *fontOptions = cairo_font_options_create();
|
||||
font = cairo_scaled_font_create(aFontFace, &sizeMatrix, &ctm, fontOptions);
|
||||
cairo_font_options_destroy(fontOptions);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||
nsIDeviceContext *aContext)
|
||||
{
|
||||
mFont = aFont;
|
||||
mLangGroup = aLangGroup;
|
||||
mDeviceContext = (nsThebesDeviceContext*)aContext;
|
||||
mDev2App = aContext->DevUnitsToAppUnits();
|
||||
|
||||
// set up the first font in the list as the default, and we'll go from there.
|
||||
mFont.EnumerateFamilies(FontEnumCallback, this);
|
||||
|
||||
mCairoFontFace = MakeCairoFontFace(mFonts[0]);
|
||||
mCairoFont = MakeCairoScaledFont(nsnull, mCairoFontFace);
|
||||
|
||||
HWND win = (HWND)mDeviceContext->GetWidget();
|
||||
HDC dc = ::GetDC(win);
|
||||
|
||||
RealizeFont(dc);
|
||||
|
||||
::ReleaseDC(win, dc);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
|
||||
void
|
||||
nsFontMetricsWin::FillLogFont(LOGFONTW* logFont, const nsString *aFontName)
|
||||
{
|
||||
float app2dev = mDeviceContext->AppUnitsToDevUnits();
|
||||
logFont->lfHeight = - NSToIntRound(mFont.size * app2dev);
|
||||
|
||||
if (logFont->lfHeight == 0) {
|
||||
logFont->lfHeight = -1;
|
||||
}
|
||||
|
||||
// Fill in logFont structure
|
||||
logFont->lfWidth = 0;
|
||||
logFont->lfEscapement = 0;
|
||||
logFont->lfOrientation = 0;
|
||||
logFont->lfUnderline =
|
||||
(mFont.decorations & NS_FONT_DECORATION_UNDERLINE)
|
||||
? TRUE : FALSE;
|
||||
logFont->lfStrikeOut =
|
||||
(mFont.decorations & NS_FONT_DECORATION_LINE_THROUGH)
|
||||
? TRUE : FALSE;
|
||||
logFont->lfCharSet = DEFAULT_CHARSET;
|
||||
#ifndef WINCE
|
||||
logFont->lfOutPrecision = OUT_TT_PRECIS;
|
||||
#else
|
||||
logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
#endif
|
||||
logFont->lfClipPrecision = CLIP_TURNOFF_FONTASSOCIATION;
|
||||
logFont->lfQuality = DEFAULT_QUALITY;
|
||||
logFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||
logFont->lfWeight = mFont.weight;
|
||||
logFont->lfItalic = (mFont.style & (NS_FONT_STYLE_ITALIC | NS_FONT_STYLE_OBLIQUE))
|
||||
? TRUE : FALSE; // XXX need better oblique support
|
||||
|
||||
int len = PR_MIN(aFontName->Length(), LF_FACESIZE);
|
||||
memcpy(logFont->lfFaceName, aFontName->get(), len * 2);
|
||||
logFont->lfFaceName[len] = '\0';
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::Destroy()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetXHeight(nscoord& aResult)
|
||||
{
|
||||
aResult = mXHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetSuperscriptOffset(nscoord& aResult)
|
||||
{
|
||||
aResult = mSuperscriptOffset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetSubscriptOffset(nscoord& aResult)
|
||||
{
|
||||
aResult = mSubscriptOffset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetStrikeout(nscoord& aOffset, nscoord& aSize)
|
||||
{
|
||||
aOffset = mStrikeoutOffset;
|
||||
aSize = mStrikeoutSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetUnderline(nscoord& aOffset, nscoord& aSize)
|
||||
{
|
||||
aOffset = mUnderlineOffset;
|
||||
aSize = mUnderlineSize;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetHeight(nscoord &aHeight)
|
||||
{
|
||||
aHeight = mMaxHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetInternalLeading(nscoord &aLeading)
|
||||
{
|
||||
aLeading = mInternalLeading;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetExternalLeading(nscoord &aLeading)
|
||||
{
|
||||
aLeading = mExternalLeading;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetEmHeight(nscoord &aHeight)
|
||||
{
|
||||
aHeight = mEmHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetEmAscent(nscoord &aAscent)
|
||||
{
|
||||
aAscent = mEmAscent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetEmDescent(nscoord &aDescent)
|
||||
{
|
||||
aDescent = mEmDescent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetMaxHeight(nscoord &aHeight)
|
||||
{
|
||||
aHeight = mMaxHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetMaxAscent(nscoord &aAscent)
|
||||
{
|
||||
aAscent = mMaxAscent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetMaxDescent(nscoord &aDescent)
|
||||
{
|
||||
aDescent = mMaxDescent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetMaxAdvance(nscoord &aAdvance)
|
||||
{
|
||||
aAdvance = mMaxAdvance;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetLangGroup(nsIAtom** aLangGroup)
|
||||
{
|
||||
*aLangGroup = mLangGroup;
|
||||
NS_IF_ADDREF(*aLangGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetFontHandle(nsFontHandle &aHandle)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetAveCharWidth(nscoord& aAveCharWidth)
|
||||
{
|
||||
aAveCharWidth = mAveCharWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetSpaceWidth(nscoord& aSpaceCharWidth)
|
||||
{
|
||||
aSpaceCharWidth = mSpaceWidth;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetLeading(nscoord& aLeading)
|
||||
{
|
||||
aLeading = mInternalLeading;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFontMetricsWin::GetNormalLineHeight(nscoord& aLineHeight)
|
||||
{
|
||||
aLineHeight = mEmHeight + mInternalLeading;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PRInt32
|
||||
nsFontMetricsWin::MeasureOrDrawUniscribe(nsThebesRenderingContext *aContext,
|
||||
const PRUnichar *aString, PRUint32 aLength,
|
||||
PRBool aDraw, PRInt32 aX, PRInt32 aY, const PRInt32 *aSpacing)
|
||||
{
|
||||
HDC aDC = (HDC)aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_WINDOWS_DC);
|
||||
|
||||
float app2dev = mDeviceContext->AppUnitsToDevUnits();
|
||||
|
||||
int loops = 0;
|
||||
|
||||
cairo_t *cr = (cairo_t*)aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_CAIRO_CONTEXT);
|
||||
|
||||
PRBool isComplex = (::ScriptIsComplex(aString, aLength, SIC_COMPLEX) == S_OK);
|
||||
|
||||
PRInt32 length = 0;
|
||||
HRESULT rv;
|
||||
int numItems, maxItems = 2;
|
||||
|
||||
SCRIPT_CACHE sc = NULL;
|
||||
SCRIPT_CONTROL *control = nsnull;
|
||||
SCRIPT_STATE *state = nsnull;
|
||||
PRBool rtl = ((::GetTextAlign(aDC) & TA_RTLREADING) == TA_RTLREADING);
|
||||
if (rtl) {
|
||||
control = (SCRIPT_CONTROL *)malloc(sizeof(SCRIPT_CONTROL));
|
||||
state = (SCRIPT_STATE *)malloc(sizeof(SCRIPT_STATE));
|
||||
memset(control, 0, sizeof(control));
|
||||
memset(state, 0, sizeof(state));
|
||||
control->fNeutralOverride = 1;
|
||||
state->uBidiLevel = 1;
|
||||
}
|
||||
|
||||
SCRIPT_ITEM *items = (SCRIPT_ITEM *)malloc(maxItems*sizeof(SCRIPT_ITEM));
|
||||
while ((rv = ScriptItemize(aString, aLength, maxItems, control, state,
|
||||
items, &numItems)) == E_OUTOFMEMORY) {
|
||||
maxItems *= 2;
|
||||
items = (SCRIPT_ITEM *)realloc(items, maxItems*sizeof(SCRIPT_ITEM));
|
||||
}
|
||||
|
||||
for (int h=0; h<numItems; h++) {
|
||||
int i = (rtl) ? numItems - h - 1 : h;
|
||||
const PRUnichar *itemChars = aString + items[i].iCharPos;
|
||||
PRUint32 itemLength = items[i+1].iCharPos - items[i].iCharPos;
|
||||
int numGlyphs = 0, maxGlyphs = 1.5 * itemLength + 16;
|
||||
WORD *glyphs = (WORD *)malloc(maxGlyphs*sizeof(WORD));
|
||||
WORD *clusters = (WORD *)malloc(itemLength*sizeof(WORD));
|
||||
SCRIPT_VISATTR *attr = (SCRIPT_VISATTR *)malloc(maxGlyphs*sizeof(SCRIPT_VISATTR));
|
||||
items[i].a.fLogicalOrder = 1;
|
||||
|
||||
cairo_font_face_t *fontFace = nsnull;
|
||||
cairo_scaled_font_t *scaledFont = nsnull;
|
||||
|
||||
TRY_AGAIN:
|
||||
int fontIndex = 0;
|
||||
|
||||
TRY_AGAIN_SAME_SCRIPT:
|
||||
loops++;
|
||||
SaveDC(aDC);
|
||||
|
||||
if (fontFace && scaledFont) {
|
||||
cairo_font_face_destroy(fontFace);
|
||||
cairo_scaled_font_destroy(scaledFont);
|
||||
}
|
||||
|
||||
fontFace = MakeCairoFontFace(mFonts[fontIndex]);
|
||||
scaledFont = MakeCairoScaledFont(cr, fontFace);
|
||||
|
||||
cairo_set_font_face(cr, fontFace);
|
||||
cairo_set_font_size(cr, NSToIntRound(mFont.size * app2dev));
|
||||
cairo_win32_scaled_font_select_font(scaledFont, aDC);
|
||||
double cairofontfactor = cairo_win32_scaled_font_get_metrics_factor(scaledFont);
|
||||
|
||||
if (!isComplex)
|
||||
items[i].a.eScript = SCRIPT_UNDEFINED;
|
||||
|
||||
while ((rv = ScriptShape(aDC, &sc, itemChars, itemLength,
|
||||
maxGlyphs, &items[i].a,
|
||||
glyphs, clusters,
|
||||
attr, &numGlyphs)) == E_OUTOFMEMORY) {
|
||||
maxGlyphs *= 2;
|
||||
glyphs = (WORD *)realloc(glyphs, maxGlyphs*sizeof(WORD));
|
||||
attr = (SCRIPT_VISATTR *)realloc(attr, maxGlyphs*sizeof(SCRIPT_VISATTR));
|
||||
}
|
||||
|
||||
if (rv == USP_E_SCRIPT_NOT_IN_FONT) {
|
||||
if (fontIndex < mFonts.Count() - 1) {
|
||||
fontIndex++;
|
||||
cairo_win32_scaled_font_done_font(scaledFont);
|
||||
RestoreDC(aDC, -1);
|
||||
goto TRY_AGAIN_SAME_SCRIPT;
|
||||
} else {
|
||||
// try again with SCRIPT_UNDEFINED
|
||||
items[i].a.eScript = SCRIPT_UNDEFINED;
|
||||
cairo_win32_scaled_font_done_font(scaledFont);
|
||||
RestoreDC(aDC, -1);
|
||||
goto TRY_AGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
if (numGlyphs > 0 && glyphs[0] == 0) {
|
||||
if (fontIndex < mFonts.Count() - 1) {
|
||||
fontIndex++;
|
||||
cairo_win32_scaled_font_done_font(scaledFont);
|
||||
RestoreDC(aDC, -1);
|
||||
goto TRY_AGAIN_SAME_SCRIPT;
|
||||
}
|
||||
// otherwise we fail to draw the characters so give up and continue on.
|
||||
}
|
||||
|
||||
if (rv == 0) {
|
||||
|
||||
ABC abc;
|
||||
GOFFSET *offsets = (GOFFSET *)malloc(numGlyphs*sizeof(GOFFSET));
|
||||
int *advance = (int *)malloc(numGlyphs*sizeof(int));
|
||||
rv = ScriptPlace(aDC, &sc, glyphs, numGlyphs, attr, &items[i].a,
|
||||
advance, offsets, &abc);
|
||||
|
||||
if (rv != S_OK)
|
||||
printf("error ScriptPlacing\n");
|
||||
#ifdef DEBUG_tor
|
||||
fprintf(stderr, "ABC[%d]: %d %d %d\n", i, abc.abcA, abc.abcB, abc.abcC);
|
||||
#endif
|
||||
|
||||
if (!aDraw) {
|
||||
length += NSToCoordRound((abc.abcA + abc.abcB + abc.abcC) * cairofontfactor * (mFont.size * app2dev);
|
||||
} else {
|
||||
PRInt32 *spacing = 0;
|
||||
PRInt32 justTotal = 0;
|
||||
if (aSpacing) {
|
||||
/* need to correct for layout/gfx spacing mismatch */
|
||||
#ifdef DEBUG_tor
|
||||
fprintf(stderr, "advn: ");
|
||||
for (int j=0; j<numGlyphs; j++) {
|
||||
fprintf(stderr, "%4d,", advance[j]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "clus: ");
|
||||
for (j=0; j<itemLength; j++)
|
||||
fprintf(stderr, "%4d,", clusters[j]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "attr: ");
|
||||
for (j=0; j<numGlyphs; j++)
|
||||
fprintf(stderr, "0x%2x,", attr[j]);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
// hacky inefficient justification: take the excess of what layout
|
||||
// thinks the width is over what uniscribe thinks the width is and
|
||||
// share it evenly between the justification opportunities
|
||||
PRInt32 layoutTotal = 0;
|
||||
for (PRUint32 j = items[i].iCharPos; j < items[i+1].iCharPos; j++) {
|
||||
layoutTotal += NSToIntRound(aSpacing[j] * app2dev);
|
||||
}
|
||||
PRInt32 gfxTotal = abc.abcA + abc.abcB + abc.abcC;
|
||||
if (layoutTotal > gfxTotal) {
|
||||
spacing = (PRInt32 *)malloc(numGlyphs*sizeof(PRInt32));
|
||||
justTotal = layoutTotal - gfxTotal;
|
||||
#if 0
|
||||
ScriptJustify(attr, advance, numGlyphs, justTotal, 1, spacing);
|
||||
#else
|
||||
memcpy(spacing, advance, sizeof(PRInt32)*numGlyphs);
|
||||
|
||||
int justOpps = 0;
|
||||
int lookForOpp = 0;
|
||||
for (j = 0; j < numGlyphs-1; j++) {
|
||||
if (attr[j+1].uJustification > 1) {
|
||||
++justOpps;
|
||||
}
|
||||
}
|
||||
if (justOpps > 0) {
|
||||
int eachJust = justTotal / justOpps;
|
||||
|
||||
for (j=0; j<numGlyphs-1; j++) {
|
||||
if (attr[j+1].uJustification > 1) {
|
||||
--justOpps;
|
||||
if (justOpps == 0) {
|
||||
spacing[j] += justTotal;
|
||||
} else {
|
||||
spacing[j] += eachJust;
|
||||
justTotal -= eachJust;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_tor
|
||||
fprintf(stderr, "hand: ");
|
||||
for (j=0; j<numGlyphs; j++) {
|
||||
fprintf(stderr, "%4d,", spacing[j]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
double cairoToPixels = cairofontfactor * (mFont.size * app2dev);
|
||||
|
||||
cairo_glyph_t *cglyphs = (cairo_glyph_t*)malloc(numGlyphs*sizeof(cairo_glyph_t));
|
||||
PRInt32 offset = 0;
|
||||
for (PRInt32 k = 0; k < numGlyphs; k++) {
|
||||
cglyphs[k].index = glyphs[k];
|
||||
cglyphs[k].x = aX + offset + NSToCoordRound(offsets[k].du * cairoToPixels);
|
||||
cglyphs[k].y = aY + NSToCoordRound(offsets[k].dv * cairoToPixels);
|
||||
offset += NSToCoordRound(advance[k] * cairoToPixels);
|
||||
#if 0
|
||||
if (aSpacing)
|
||||
offset += NSToIntRound(aSpacing[k] * app2dev) * cairoToPixels;
|
||||
#endif
|
||||
}
|
||||
|
||||
cairo_show_glyphs(cr, cglyphs, numGlyphs);
|
||||
|
||||
free(cglyphs);
|
||||
|
||||
|
||||
aX += NSToCoordRound((abs(abc.abcA) + abc.abcB + abs(abc.abcC) + justTotal) * cairoToPixels);
|
||||
free(spacing);
|
||||
}
|
||||
free(offsets);
|
||||
free(advance);
|
||||
|
||||
cairo_font_face_destroy(fontFace);
|
||||
cairo_scaled_font_destroy(scaledFont);
|
||||
|
||||
cairo_win32_scaled_font_done_font(scaledFont);
|
||||
|
||||
RestoreDC(aDC, -1);
|
||||
|
||||
}
|
||||
free(glyphs);
|
||||
free(clusters);
|
||||
free(attr);
|
||||
|
||||
}
|
||||
|
||||
free(items);
|
||||
|
||||
// printf("loops: %d\n", loops - numItems);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsFontMetricsWin::GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth,
|
||||
nsThebesRenderingContext *aContext)
|
||||
{
|
||||
PRInt32 aFontID = 0;
|
||||
return GetWidth(PromiseFlatString(NS_ConvertUTF8toUTF16(aString, aLength)).get(),
|
||||
aLength, aWidth, &aFontID, aContext);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontMetricsWin::GetWidth(const PRUnichar* aString, PRUint32 aLength,
|
||||
nscoord& aWidth, PRInt32 *aFontID,
|
||||
nsThebesRenderingContext *aContext)
|
||||
{
|
||||
// if (::ScriptIsComplex(aString, aLength, SIC_COMPLEX) == S_OK) {
|
||||
aWidth = MeasureOrDrawUniscribe(aContext, aString, aLength, PR_FALSE, 0, 0, NULL);
|
||||
|
||||
float f;
|
||||
f = mDeviceContext->DevUnitsToAppUnits();
|
||||
aWidth = NSToCoordRound(aWidth * f);
|
||||
|
||||
#if 0
|
||||
} else {
|
||||
::GetTextExtentPoint32W(aDC, aString, aLength, &size);
|
||||
size.cx -= mOverhangCorrection;
|
||||
return size.cx;
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
// Get the text dimensions for this string
|
||||
nsresult
|
||||
nsFontMetricsWin::GetTextDimensions(const PRUnichar* aString,
|
||||
PRUint32 aLength,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32* aFontID)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFontMetricsWin::GetTextDimensions(const char* aString,
|
||||
PRInt32 aLength,
|
||||
PRInt32 aAvailWidth,
|
||||
PRInt32* aBreaks,
|
||||
PRInt32 aNumBreaks,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32& aNumCharsFit,
|
||||
nsTextDimensions& aLastWordDimensions,
|
||||
PRInt32* aFontID)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult
|
||||
nsFontMetricsWin::GetTextDimensions(const PRUnichar* aString,
|
||||
PRInt32 aLength,
|
||||
PRInt32 aAvailWidth,
|
||||
PRInt32* aBreaks,
|
||||
PRInt32 aNumBreaks,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32& aNumCharsFit,
|
||||
nsTextDimensions& aLastWordDimensions,
|
||||
PRInt32* aFontID)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Draw a string using this font handle on the surface passed in.
|
||||
nsresult
|
||||
nsFontMetricsWin::DrawString(const char *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
const nscoord* aSpacing,
|
||||
nsThebesRenderingContext *aContext)
|
||||
{
|
||||
return DrawString(PromiseFlatString(NS_ConvertUTF8toUTF16(aString, aLength)).get(),
|
||||
aLength, aX, aY, 0, aSpacing, aContext);
|
||||
}
|
||||
|
||||
// aCachedOffset will be updated with a new offset.
|
||||
nsresult
|
||||
nsFontMetricsWin::DrawString(const PRUnichar* aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
PRInt32 aFontID,
|
||||
const nscoord* aSpacing,
|
||||
nsThebesRenderingContext *aContext)
|
||||
{
|
||||
float app2dev = mDeviceContext->AppUnitsToDevUnits();
|
||||
MeasureOrDrawUniscribe(aContext, aString, aLength, PR_TRUE,
|
||||
NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev), aSpacing);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#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.
|
||||
nsresult
|
||||
nsFontMetricsWin::GetBoundingMetrics(const char *aString, PRUint32 aLength,
|
||||
nsBoundingMetrics &aBoundingMetrics)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// aCachedOffset will be updated with a new offset.
|
||||
nsresult
|
||||
nsFontMetricsWin::GetBoundingMetrics(const PRUnichar *aString,
|
||||
PRUint32 aLength,
|
||||
nsBoundingMetrics &aBoundingMetrics,
|
||||
PRInt32 *aFontID)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif /* MOZ_MATHML */
|
||||
|
||||
// Set the direction of the text rendering
|
||||
nsresult
|
||||
nsFontMetricsWin::SetRightToLeftText(PRBool aIsRTL)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
nsFontMetricsWin::RealizeFont(HDC dc)
|
||||
{
|
||||
float app2dev = mDeviceContext->AppUnitsToDevUnits();
|
||||
|
||||
SaveDC(dc);
|
||||
|
||||
cairo_win32_scaled_font_select_font(mCairoFont, dc);
|
||||
|
||||
double cairofontfactor = cairo_win32_scaled_font_get_metrics_factor(mCairoFont);
|
||||
double multiplier = mDev2App * cairofontfactor * NSToIntRound(mFont.size * app2dev);
|
||||
|
||||
// Get font metrics
|
||||
OUTLINETEXTMETRIC oMetrics;
|
||||
TEXTMETRIC& metrics = oMetrics.otmTextMetrics;
|
||||
nscoord onePixel = NSToCoordRound(1 * mDev2App);
|
||||
nscoord descentPos = 0;
|
||||
|
||||
if (0 < ::GetOutlineTextMetrics(dc, sizeof(oMetrics), &oMetrics)) {
|
||||
// mXHeight = NSToCoordRound(oMetrics.otmsXHeight * mDev2App); XXX not really supported on windows
|
||||
mXHeight = NSToCoordRound((float)metrics.tmAscent * multiplier * 0.56f); // 50% of ascent, best guess for true type
|
||||
mSuperscriptOffset = NSToCoordRound(oMetrics.otmptSuperscriptOffset.y * multiplier);
|
||||
mSubscriptOffset = NSToCoordRound(oMetrics.otmptSubscriptOffset.y * multiplier);
|
||||
|
||||
mStrikeoutSize = PR_MAX(onePixel, NSToCoordRound(oMetrics.otmsStrikeoutSize * multiplier));
|
||||
mStrikeoutOffset = NSToCoordRound(oMetrics.otmsStrikeoutPosition * multiplier);
|
||||
mUnderlineSize = PR_MAX(onePixel, NSToCoordRound(oMetrics.otmsUnderscoreSize * multiplier));
|
||||
|
||||
mUnderlineOffset = NSToCoordRound(oMetrics.otmsUnderscorePosition * multiplier);
|
||||
|
||||
// Begin -- section of code to get the real x-height with GetGlyphOutline()
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 mMat = { 1, 0, 0, 1 }; // glyph transform matrix (always identity in our context)
|
||||
DWORD len = GetGlyphOutlineW(dc, PRUnichar('x'), GGO_METRICS, &gm, 0, nsnull, &mMat);
|
||||
|
||||
if (GDI_ERROR != len && gm.gmptGlyphOrigin.y > 0) {
|
||||
mXHeight = NSToCoordRound(gm.gmptGlyphOrigin.y * multiplier);
|
||||
}
|
||||
// End -- getting x-height
|
||||
}
|
||||
else {
|
||||
// Make a best-effort guess at extended metrics
|
||||
// this is based on general typographic guidelines
|
||||
::GetTextMetrics(dc, &metrics);
|
||||
mXHeight = NSToCoordRound((float)metrics.tmAscent * mDev2App * 0.56f); // 56% of ascent, best guess for non-true type
|
||||
mSuperscriptOffset = mXHeight; // XXX temporary code!
|
||||
mSubscriptOffset = mXHeight; // XXX temporary code!
|
||||
|
||||
mStrikeoutSize = onePixel; // XXX this is a guess
|
||||
mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0f); // 50% of xHeight
|
||||
mUnderlineSize = onePixel; // XXX this is a guess
|
||||
mUnderlineOffset = -NSToCoordRound((float)metrics.tmDescent * mDev2App * 0.30f); // 30% of descent
|
||||
}
|
||||
|
||||
|
||||
mInternalLeading = NSToCoordRound(metrics.tmInternalLeading * multiplier);
|
||||
mExternalLeading = NSToCoordRound(metrics.tmExternalLeading * multiplier);
|
||||
mEmHeight = NSToCoordRound((metrics.tmHeight - metrics.tmInternalLeading) *
|
||||
multiplier);
|
||||
mEmAscent = NSToCoordRound((metrics.tmAscent - metrics.tmInternalLeading) *
|
||||
multiplier);
|
||||
mEmDescent = NSToCoordRound(metrics.tmDescent * multiplier);
|
||||
mMaxHeight = NSToCoordRound(metrics.tmHeight * multiplier);
|
||||
mMaxAscent = NSToCoordRound(metrics.tmAscent * multiplier);
|
||||
mMaxDescent = NSToCoordRound(metrics.tmDescent * multiplier);
|
||||
mMaxAdvance = NSToCoordRound(metrics.tmMaxCharWidth * multiplier);
|
||||
mAveCharWidth = PR_MAX(1, NSToCoordRound(metrics.tmAveCharWidth * multiplier));
|
||||
|
||||
#if 0
|
||||
// descent position is preferred, but we need to make sure there is enough
|
||||
// space available. Baseline need to be raised so that underline will stay
|
||||
// within boundary.
|
||||
// only do this for CJK to minimize possible risk
|
||||
if (IsCJKLangGroupAtom(mLangGroup.get())) {
|
||||
if (gDoingLineheightFixup &&
|
||||
mInternalLeading+mExternalLeading > mUnderlineSize &&
|
||||
descentPos < mUnderlineOffset) {
|
||||
mEmAscent -= mUnderlineSize;
|
||||
mEmDescent += mUnderlineSize;
|
||||
mMaxAscent -= mUnderlineSize;
|
||||
mMaxDescent += mUnderlineSize;
|
||||
mUnderlineOffset = descentPos;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Cache the width of a single space.
|
||||
SIZE size;
|
||||
::GetTextExtentPoint32(dc, " ", 1, &size);
|
||||
//size.cx -= font->mOverhangCorrection;
|
||||
mSpaceWidth = NSToCoordRound(size.cx * multiplier);
|
||||
|
||||
cairo_win32_scaled_font_done_font(mCairoFont);
|
||||
|
||||
RestoreDC(dc, -1);
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 <blizzard@mozilla.org>.
|
||||
* 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 __nsIThebesFontMetrics_h
|
||||
#define __nsIThebesFontMetrics_h
|
||||
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
|
||||
class nsThebesRenderingContext;
|
||||
|
||||
class nsIThebesFontMetrics : 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, nsThebesRenderingContext *aContext) = 0;
|
||||
// aCachedOffset will be updated with a new offset.
|
||||
virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength,
|
||||
nscoord& aWidth, PRInt32 *aFontID,
|
||||
nsThebesRenderingContext *aContext) = 0;
|
||||
|
||||
// Get the text dimensions for this string
|
||||
virtual nsresult GetTextDimensions(const PRUnichar* aString,
|
||||
PRUint32 aLength,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32* aFontID) = 0;
|
||||
virtual nsresult GetTextDimensions(const char* aString,
|
||||
PRInt32 aLength,
|
||||
PRInt32 aAvailWidth,
|
||||
PRInt32* aBreaks,
|
||||
PRInt32 aNumBreaks,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32& aNumCharsFit,
|
||||
nsTextDimensions& aLastWordDimensions,
|
||||
PRInt32* aFontID) = 0;
|
||||
virtual nsresult GetTextDimensions(const PRUnichar* aString,
|
||||
PRInt32 aLength,
|
||||
PRInt32 aAvailWidth,
|
||||
PRInt32* aBreaks,
|
||||
PRInt32 aNumBreaks,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32& aNumCharsFit,
|
||||
nsTextDimensions& aLastWordDimensions,
|
||||
PRInt32* aFontID) = 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,
|
||||
nsThebesRenderingContext *aContext) = 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,
|
||||
nsThebesRenderingContext *aContext) = 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) = 0;
|
||||
// aCachedOffset will be updated with a new offset.
|
||||
virtual nsresult GetBoundingMetrics(const PRUnichar *aString,
|
||||
PRUint32 aLength,
|
||||
nsBoundingMetrics &aBoundingMetrics,
|
||||
PRInt32 *aFontID) = 0;
|
||||
#endif /* MOZ_MATHML */
|
||||
|
||||
// Set the direction of the text rendering
|
||||
virtual nsresult SetRightToLeftText(PRBool aIsRTL) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif /* __nsIThebesFontMetrics_h */
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 <blizzard@mozilla.org>.
|
||||
* 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 __nsIThebesRenderingContext_h
|
||||
#define __nsIThebesRenderingContext_h
|
||||
|
||||
#include "nsIRenderingContext.h"
|
||||
|
||||
// IID for the nsIRenderingContext interface
|
||||
#define NSI_THEBES_RENDERING_CONTEXT_IID \
|
||||
{ 0x8591c4c6, 0x41d4, 0x485a, \
|
||||
{ 0xb2, 0x4f, 0x9d, 0xe1, 0x9b, 0x69, 0xce, 0x02 } }
|
||||
|
||||
class nsIThebesRenderingContext : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NSI_THEBES_RENDERING_CONTEXT_IID)
|
||||
|
||||
NS_IMETHOD CreateDrawingSurface(nsNativeWidget aWidget, nsIDrawingSurface* &aSurface) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif /* __nsIThebesRenderingContext_h */
|
|
@ -0,0 +1,340 @@
|
|||
|
||||
// for strtod()
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nsIRenderingContext.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include <pango/pangox.h>
|
||||
#include <pango/pango-fontmap.h>
|
||||
|
||||
#include "nsSystemFontsGTK2.h"
|
||||
|
||||
static PRInt32 GetXftDPI(void);
|
||||
static void AppendFontFFREName(nsString& aString, const char* aXLFDName);
|
||||
|
||||
#define DEFAULT_TWIP_FONT_SIZE 240
|
||||
|
||||
nsSystemFontsGTK2::nsSystemFontsGTK2(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
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_COREXFONTS
|
||||
static void xlfd_from_pango_font_description(GtkWidget *aWidget,
|
||||
const PangoFontDescription *aFontDesc,
|
||||
nsString& aFontName);
|
||||
#endif /* MOZ_ENABLE_COREXFONTS */
|
||||
|
||||
nsresult
|
||||
nsSystemFontsGTK2::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
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
#if 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 *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);
|
||||
}
|
||||
#endif /* MOZ_ENABLE_COREXFONTS */
|
||||
|
||||
#if defined(MOZ_ENABLE_COREXFONTS) || defined(MOZ_WIDGET_GTK)
|
||||
|
||||
#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 || MOZ_WIDGET_GTK*/
|
||||
|
||||
#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 */
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
#ifndef _NS_SYSTEMFONTSGTK2_H_
|
||||
#define _NS_SYSTEMFONTSGTK2_H_
|
||||
|
||||
#include <nsFont.h>
|
||||
|
||||
class nsSystemFontsGTK2
|
||||
{
|
||||
public:
|
||||
nsSystemFontsGTK2(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;
|
||||
};
|
||||
|
||||
#endif /* _NS_SYSTEMFONTSGTK2_H_ */
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef _NS_SYSTEMFONTSWIN_H_
|
||||
#define _NS_SYSTEMFONTSWIN_H_
|
||||
|
||||
#include <nsFont.h>
|
||||
#include <nsIDeviceContext.h>
|
||||
|
||||
class nsSystemFontsWin
|
||||
{
|
||||
public:
|
||||
nsSystemFontsWin(float aPixelsToTwips);
|
||||
|
||||
nsresult CopyLogFontToNSFont(HDC* aHDC, const LOGFONT* ptrLogFont,
|
||||
nsFont* aFont, PRBool aIsWide = PR_FALSE) const;
|
||||
nsresult GetSysFontInfo(HDC aHDC, nsSystemFontID anID, nsFont* aFont) const;
|
||||
nsresult GetSystemFont(nsSystemFontID anID, nsFont *aFont) const;
|
||||
};
|
||||
|
||||
#endif /* _NS_SYSTEMFONTSWIN_H_ */
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 "nsMemory.h"
|
||||
|
||||
#include "nsThebesBlender.h"
|
||||
#include "nsThebesDrawingSurface.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesBlender, nsIBlender)
|
||||
|
||||
nsThebesBlender::nsThebesBlender()
|
||||
: mThebesDC(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
nsThebesBlender::~nsThebesBlender()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesBlender::Init(nsIDeviceContext *aContext)
|
||||
{
|
||||
mThebesDC = NS_STATIC_CAST(nsThebesDeviceContext*, aContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesBlender::Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
|
||||
nsIDrawingSurface* aSrc, nsIDrawingSurface* aDest,
|
||||
PRInt32 aDX, PRInt32 aDY,
|
||||
float aSrcOpacity,
|
||||
nsIDrawingSurface* aSecondSrc,
|
||||
nscolor aSrcBackColor, nscolor aSecondSrcBackColor)
|
||||
{
|
||||
NS_WARNING("Should be using Push/PopFilter instead");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesBlender::Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
|
||||
nsIRenderingContext *aSrc, nsIRenderingContext *aDest,
|
||||
PRInt32 aDX, PRInt32 aDY, float aSrcOpacity,
|
||||
nsIRenderingContext *aSecondSrc, nscolor aSrcBackColor,
|
||||
nscolor aSecondSrcBackColor)
|
||||
{
|
||||
NS_WARNING("Should be using Push/PopFilter instead");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesBlender::GetAlphas(const nsRect& aRect, nsIDrawingSurface* aBlack,
|
||||
nsIDrawingSurface* aWhite, PRUint8** aAlphas)
|
||||
{
|
||||
NS_WARNING("This needs to be implemented somehow");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
|
@ -0,0 +1,537 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
*
|
||||
* 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 "nsIServiceManager.h"
|
||||
|
||||
#include "nsThebesDeviceContext.h"
|
||||
#include "nsThebesRenderingContext.h"
|
||||
#include "nsThebesDrawingSurface.h"
|
||||
|
||||
#include "nsIView.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
// for getenv
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include "nsFontMetricsUtils.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include <pango/pangox.h>
|
||||
#include <pango/pango-fontmap.h>
|
||||
|
||||
|
||||
#ifdef MOZ_ENABLE_GLITZ
|
||||
#include "glitz-glx.h"
|
||||
#endif /* GLITZ */
|
||||
#endif /* GTK2 */
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
#include "nsSystemFontsGTK2.h"
|
||||
static nsSystemFontsGTK2 *gSystemFonts = nsnull;
|
||||
#elif XP_WIN
|
||||
#include <cairo-win32.h>
|
||||
#include "nsSystemFontsWin.h"
|
||||
static nsSystemFontsWin *gSystemFonts = nsnull;
|
||||
#include <Usp10.h>
|
||||
#else
|
||||
#error Need to declare gSystemFonts!
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
extern "C" {
|
||||
static int x11_error_handler (Display *dpy, XErrorEvent *err) {
|
||||
NS_ASSERTION(PR_FALSE, "X Error");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* gThebesGFXLog = nsnull;
|
||||
#endif
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsThebesDeviceContext, DeviceContextImpl)
|
||||
|
||||
nsThebesDeviceContext::nsThebesDeviceContext()
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gThebesGFXLog)
|
||||
gThebesGFXLog = PR_NewLogModule("thebesGfx");
|
||||
#endif
|
||||
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("#### Creating DeviceContext %p\n", this));
|
||||
|
||||
mDevUnitsToAppUnits = 1.0f;
|
||||
mAppUnitsToDevUnits = 1.0f;
|
||||
mCPixelScale = 1.0f;
|
||||
mZoom = 1.0f;
|
||||
mTextZoom = 1.0f;
|
||||
|
||||
mWidgetSurfaceCache.Init();
|
||||
|
||||
#ifdef XP_WIN
|
||||
SCRIPT_DIGITSUBSTITUTE sds;
|
||||
ScriptRecordDigitSubstitution(LOCALE_USER_DEFAULT, &sds);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsThebesDeviceContext::~nsThebesDeviceContext()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::Init(nsNativeWidget aWidget)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
// XXX we should really look at the widget for printing and such, but this widget is currently always null...
|
||||
HDC dc = GetDC(nsnull);
|
||||
mPixelsToTwips = (float)NSIntPointsToTwips(72) / (float)GetDeviceCaps(dc, LOGPIXELSY);
|
||||
if (GetDeviceCaps(dc, TECHNOLOGY) == DT_RASDISPLAY)
|
||||
mPixelsToTwips = (float)NSToIntRound(mPixelsToTwips);
|
||||
mTwipsToPixels = 1.0f / mPixelsToTwips;
|
||||
ReleaseDC(nsnull, dc);
|
||||
#else
|
||||
mTwipsToPixels = 96 / (float) NSIntPointsToTwips(72);
|
||||
mPixelsToTwips = 1.0f / mTwipsToPixels;
|
||||
#endif
|
||||
|
||||
mWidget = aWidget;
|
||||
|
||||
if (!mScreenManager)
|
||||
mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
|
||||
if (!mScreenManager)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
mScreenManager->GetPrimaryScreen (getter_AddRefs(screen));
|
||||
if (screen) {
|
||||
PRInt32 x, y, width, height;
|
||||
screen->GetRect (&x, &y, &width, &height);
|
||||
mWidthFloat = float(width);
|
||||
mHeightFloat = float(height);
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
if (getenv ("MOZ_X_SYNC")) {
|
||||
PR_LOG (gThebesGFXLog, PR_LOG_DEBUG, ("+++ Enabling XSynchronize\n"));
|
||||
XSynchronize (gdk_x11_get_default_xdisplay(), True);
|
||||
XSetErrorHandler(x11_error_handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
mWidth = -1;
|
||||
mHeight = -1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::CreateRenderingContext(nsIView *aView,
|
||||
nsIRenderingContext *&aContext)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aView);
|
||||
NS_PRECONDITION(aView->HasWidget(), "View has no widget!");
|
||||
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
widget = aView->GetWidget();
|
||||
|
||||
return CreateRenderingContext(widget, aContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::CreateRenderingContext(nsIDrawingSurface *aSurface,
|
||||
nsIRenderingContext *&aContext)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
aContext = nsnull;
|
||||
nsCOMPtr<nsIRenderingContext> pContext;
|
||||
rv = CreateRenderingContextInstance(*getter_AddRefs(pContext));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = pContext->Init(this, aSurface);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aContext = pContext;
|
||||
NS_ADDREF(aContext);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::CreateRenderingContext(nsIWidget *aWidget,
|
||||
nsIRenderingContext *&aContext)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
aContext = nsnull;
|
||||
nsCOMPtr<nsIRenderingContext> pContext;
|
||||
rv = CreateRenderingContextInstance(*getter_AddRefs(pContext));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = pContext->Init(this, aWidget);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aContext = pContext;
|
||||
NS_ADDREF(aContext);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::CreateRenderingContext(nsIRenderingContext *&aContext)
|
||||
{
|
||||
NS_ERROR("CreateRenderingContext with other rendering context arg; fix this if this needs to be called");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::CreateRenderingContextInstance(nsIRenderingContext *&aContext)
|
||||
{
|
||||
nsCOMPtr<nsIRenderingContext> renderingContext = new nsThebesRenderingContext();
|
||||
if (!renderingContext)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
aContext = renderingContext;
|
||||
NS_ADDREF(aContext);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::SupportsNativeWidgets(PRBool &aSupportsWidgets)
|
||||
{
|
||||
aSupportsWidgets = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetScrollBarDimensions(float &aWidth, float &aHeight) const
|
||||
{
|
||||
aWidth = 10.0f * mPixelsToTwips;
|
||||
aHeight = 10.0f * mPixelsToTwips;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetSystemFont(nsSystemFontID aID, nsFont *aFont) const
|
||||
{
|
||||
nsresult status = NS_OK;
|
||||
|
||||
if (!gSystemFonts) {
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
gSystemFonts = new nsSystemFontsGTK2(mPixelsToTwips);
|
||||
#elif XP_WIN
|
||||
gSystemFonts = new nsSystemFontsWin(mPixelsToTwips);
|
||||
#else
|
||||
#error Need to know how to create gSystemFonts, fix me!
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
gSystemFonts->GetSystemFont(aID, aFont);
|
||||
return NS_OK;
|
||||
|
||||
#else
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::CheckFontExistence(const nsString& aFaceName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetDepth(PRUint32& aDepth)
|
||||
{
|
||||
aDepth = 24;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetPaletteInfo(nsPaletteInfo& aPaletteInfo)
|
||||
{
|
||||
aPaletteInfo.isPaletteDevice = PR_FALSE;
|
||||
aPaletteInfo.sizePalette = 0;
|
||||
aPaletteInfo.numReserved = 0;
|
||||
aPaletteInfo.palette = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::ConvertPixel(nscolor aColor, PRUint32 & aPixel)
|
||||
{
|
||||
aPixel = aColor;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight)
|
||||
{
|
||||
if (mWidth == -1)
|
||||
mWidth = NSToIntRound(mWidthFloat * mDevUnitsToAppUnits);
|
||||
|
||||
if (mHeight == -1)
|
||||
mHeight = NSToIntRound(mHeightFloat * mDevUnitsToAppUnits);
|
||||
|
||||
aWidth = mWidth;
|
||||
aHeight = mHeight;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetRect(nsRect &aRect)
|
||||
{
|
||||
if (mWidget) {
|
||||
PRInt32 x,y;
|
||||
PRUint32 width, height;
|
||||
|
||||
#if defined (MOZ_ENABLE_GTK2)
|
||||
Window root_ignore;
|
||||
PRUint32 bwidth_ignore, depth;
|
||||
|
||||
XGetGeometry(GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(mWidget)),
|
||||
GDK_WINDOW_XWINDOW(GDK_DRAWABLE(mWidget)),
|
||||
&root_ignore, &x, &y,
|
||||
&width, &height,
|
||||
&bwidth_ignore, &depth);
|
||||
#elif defined (XP_WIN)
|
||||
// XXX
|
||||
x = y = 0;
|
||||
width = height = 200;
|
||||
#else
|
||||
#error write me
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIScreen> 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 {
|
||||
aRect.x = 0;
|
||||
aRect.y = 0;
|
||||
|
||||
this->GetDeviceSurfaceDimensions(aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetClientRect(nsRect &aRect)
|
||||
{
|
||||
nsresult rv = this->GetRect(aRect);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if defined(MOZ_ENABLE_GLITZ)
|
||||
void*
|
||||
nsThebesDeviceContext::GetGlitzDrawableFormat()
|
||||
{
|
||||
glitz_drawable_format_t* format = nsnull;
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
glitz_drawable_format_t templ;
|
||||
memset(&templ, 0, sizeof(templ));
|
||||
templ.samples = 1; // change this to change FSAA?
|
||||
templ.types.window = 1;
|
||||
|
||||
int defaultScreen = gdk_x11_get_default_screen();
|
||||
unsigned long mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_WINDOW_MASK;
|
||||
|
||||
format = glitz_glx_find_drawable_format (GDK_DISPLAY(), defaultScreen, mask, &templ, 0);
|
||||
#endif
|
||||
return format;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_ENABLE_GLITZ) && defined(MOZ_ENABLE_GTK2)
|
||||
void*
|
||||
nsThebesDeviceContext::GetDesiredVisual()
|
||||
{
|
||||
Display* dpy = GDK_DISPLAY();
|
||||
int defaultScreen = gdk_x11_get_default_screen();
|
||||
glitz_drawable_format_t* format = (glitz_drawable_format_t*) GetGlitzDrawableFormat();
|
||||
if (format) {
|
||||
XVisualInfo* vinfo = glitz_glx_get_visual_info_from_format(dpy, defaultScreen, format);
|
||||
GdkScreen* screen = gdk_display_get_screen(gdk_x11_lookup_xdisplay(dpy), defaultScreen);
|
||||
GdkVisual* vis = gdk_x11_screen_lookup_visual(screen, vinfo->visualid);
|
||||
return vis;
|
||||
} else {
|
||||
// GL/GLX not available, force glitz off
|
||||
nsThebesDrawingSurface::mGlitzMode = 0;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::PrepareNativeWidget(nsIWidget* aWidget, void** aOut)
|
||||
{
|
||||
#if defined(MOZ_ENABLE_GLITZ) && defined(MOZ_ENABLE_GTK2)
|
||||
*aOut = GetDesiredVisual();
|
||||
#else
|
||||
*aOut = nsnull;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* below methods are for printing and are not implemented
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetDeviceContextFor(nsIDeviceContextSpec *aDevice,
|
||||
nsIDeviceContext *&aContext)
|
||||
{
|
||||
/* we don't do printing */
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::PrepareDocument(PRUnichar * aTitle,
|
||||
PRUnichar* aPrintToFileName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::BeginDocument(PRUnichar* aTitle,
|
||||
PRUnichar* aPrintToFileName,
|
||||
PRInt32 aStartPage,
|
||||
PRInt32 aEndPage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::EndDocument(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::AbortDocument(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::BeginPage(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::EndPage(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::SetAltDevice(nsIDeviceContext* aAltDC)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::GetAltDevice(nsIDeviceContext** aAltDC)
|
||||
{
|
||||
*aAltDC = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDeviceContext::SetUseAltDC(PRUint8 aValue, PRBool aOn)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** End printing methods **/
|
|
@ -0,0 +1,140 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
*
|
||||
* 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 _NS_THEBESDEVICECONTEXT_H_
|
||||
#define _NS_THEBESDEVICECONTEXT_H_
|
||||
|
||||
#include "nsIScreenManager.h"
|
||||
|
||||
#include "nsDeviceContext.h"
|
||||
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
#include <gfxContext.h>
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
extern PRLogModuleInfo* gThebesGFXLog;
|
||||
#endif
|
||||
|
||||
class nsThebesDeviceContext : public DeviceContextImpl
|
||||
{
|
||||
public:
|
||||
nsThebesDeviceContext();
|
||||
virtual ~nsThebesDeviceContext();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_IMETHOD Init(nsNativeWidget aWidget);
|
||||
NS_IMETHOD CreateRenderingContext(nsIView *aView, nsIRenderingContext *&aContext);
|
||||
|
||||
NS_IMETHOD CreateRenderingContext(nsIDrawingSurface *aSurface, nsIRenderingContext *&aContext);
|
||||
NS_IMETHOD CreateRenderingContext(nsIWidget *aWidget, nsIRenderingContext *&aContext);
|
||||
NS_IMETHOD CreateRenderingContext(nsIRenderingContext *&aContext);
|
||||
NS_IMETHOD CreateRenderingContextInstance(nsIRenderingContext *&aContext);
|
||||
|
||||
NS_IMETHOD SupportsNativeWidgets(PRBool &aSupportsWidgets);
|
||||
NS_IMETHOD PrepareNativeWidget(nsIWidget* aWidget, void** aOut);
|
||||
|
||||
NS_IMETHOD GetScrollBarDimensions(float &aWidth, float &aHeight) const;
|
||||
|
||||
NS_IMETHOD GetSystemFont(nsSystemFontID aID, nsFont *aFont) const;
|
||||
|
||||
NS_IMETHOD CheckFontExistence(const nsString& aFaceName);
|
||||
|
||||
NS_IMETHOD GetDepth(PRUint32& aDepth);
|
||||
|
||||
NS_IMETHOD GetPaletteInfo(nsPaletteInfo& aPaletteInfo);
|
||||
|
||||
NS_IMETHOD ConvertPixel(nscolor aColor, PRUint32 & aPixel);
|
||||
|
||||
NS_IMETHOD GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight);
|
||||
NS_IMETHOD GetRect(nsRect &aRect);
|
||||
NS_IMETHOD GetClientRect(nsRect &aRect);
|
||||
|
||||
#ifdef MOZ_ENABLE_GLITZ
|
||||
/* glitz_drawable_format_t */ void* GetGlitzDrawableFormat();
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
/* GdkVisual */ void* GetDesiredVisual();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* printing goop */
|
||||
NS_IMETHOD GetDeviceContextFor(nsIDeviceContextSpec *aDevice,
|
||||
nsIDeviceContext *&aContext);
|
||||
|
||||
NS_IMETHOD PrepareDocument(PRUnichar * aTitle,
|
||||
PRUnichar* aPrintToFileName);
|
||||
|
||||
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 SetAltDevice(nsIDeviceContext* aAltDC);
|
||||
NS_IMETHOD GetAltDevice(nsIDeviceContext** aAltDC);
|
||||
NS_IMETHOD SetUseAltDC(PRUint8 aValue, PRBool aOn);
|
||||
/* end printing goop */
|
||||
|
||||
static void DebugShowCairoSurface (const char *aName, cairo_surface_t *aSurface);
|
||||
|
||||
|
||||
nsNativeWidget GetWidget() { return mWidget; }
|
||||
private:
|
||||
nsNativeWidget mWidget;
|
||||
|
||||
nsCOMPtr<nsIScreenManager> mScreenManager;
|
||||
|
||||
float mWidthFloat;
|
||||
float mHeightFloat;
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
|
||||
nsRefPtrHashtable<nsISupportsHashKey, gfxASurface> mWidgetSurfaceCache;
|
||||
};
|
||||
|
||||
#endif /* _NS_CAIRODEVICECONTEXT_H_ */
|
||||
|
|
@ -0,0 +1,393 @@
|
|||
/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsThebesDrawingSurface.h"
|
||||
#include "nsThebesDeviceContext.h"
|
||||
|
||||
#include "nsMemory.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
#include <gdk/gdkx.h>
|
||||
#include "gfxXlibSurface.h"
|
||||
# ifdef MOZ_ENABLE_GLITZ
|
||||
# include "gfxGlitzSurface.h"
|
||||
# include "glitz-glx.h"
|
||||
# endif
|
||||
#elif XP_WIN
|
||||
#include "gfxWindowsSurface.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
PRInt32 nsThebesDrawingSurface::mGlitzMode = -1;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesDrawingSurface, nsIDrawingSurface)
|
||||
|
||||
nsThebesDrawingSurface::nsThebesDrawingSurface()
|
||||
{
|
||||
}
|
||||
|
||||
nsThebesDrawingSurface::~nsThebesDrawingSurface()
|
||||
{
|
||||
#ifdef WIN_XP
|
||||
if (mWidget)
|
||||
nsNativeWidget nativeWidget = mWidget->FreeNativeData(mNativeWidget, NS_NATIVE_GRAPHIC);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesDrawingSurface::Init(nsThebesDeviceContext *aDC, PRUint32 aWidth, PRUint32 aHeight, PRBool aFastAccess)
|
||||
{
|
||||
NS_ASSERTION(mSurface == nsnull, "Surface already initialized!");
|
||||
NS_ASSERTION(aWidth > 0 && aHeight > 0, "Invalid surface dimensions!");
|
||||
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsThebesDrawingSurface::Init aDC %p w %d h %d fast %d\n", this, aDC, aWidth, aHeight, aFastAccess));
|
||||
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
mDC = aDC;
|
||||
mNativeWidget = nsnull;
|
||||
|
||||
#if defined(MOZ_ENABLE_GTK2)
|
||||
if (aFastAccess) {
|
||||
//fprintf (stderr, "## nsThebesDrawingSurface::Init gfxImageSurface %d %d\n", aWidth, aHeight);
|
||||
mSurface = new gfxImageSurface(gfxImageSurface::ImageFormatARGB32, aWidth, aHeight);
|
||||
} else {
|
||||
if (!UseGlitz()) {
|
||||
mSurface = new gfxXlibSurface(GDK_DISPLAY(), GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()), aWidth, aHeight);
|
||||
} else {
|
||||
# if defined(MOZ_ENABLE_GLITZ)
|
||||
glitz_drawable_format_t *gdformat = (glitz_drawable_format_t*) aDC->GetGlitzDrawableFormat();
|
||||
glitz_drawable_t *gdraw =
|
||||
glitz_glx_create_pbuffer_drawable (GDK_DISPLAY(),
|
||||
DefaultScreen(GDK_DISPLAY()),
|
||||
gdformat,
|
||||
aWidth,
|
||||
aHeight);
|
||||
glitz_format_t *gformat =
|
||||
glitz_find_standard_format (gdraw, GLITZ_STANDARD_ARGB32);
|
||||
glitz_surface_t *gsurf =
|
||||
glitz_surface_create (gdraw,
|
||||
gformat,
|
||||
aWidth,
|
||||
aHeight,
|
||||
0,
|
||||
NULL);
|
||||
glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR, 0, 0);
|
||||
|
||||
//fprintf (stderr, "## nsThebesDrawingSurface::Init Glitz PBUFFER %d %d\n", aWidth, aHeight);
|
||||
mSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
#elif XP_WIN
|
||||
if (aFastAccess) {
|
||||
mSurface = new gfxImageSurface(gfxImageSurface::ImageFormatARGB32, aWidth, aHeight);
|
||||
} else {
|
||||
mSurface = new gfxWindowsSurface(aWidth, aHeight);
|
||||
}
|
||||
#else
|
||||
#error Write me!
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesDrawingSurface::Init (nsThebesDeviceContext *aDC, nsIWidget *aWidget)
|
||||
{
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsThebesDrawingSurface::Init aDC %p aWidget %p\n", this, aDC, aWidget));
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
nsNativeWidget nativeWidget = aWidget->GetNativeData(NS_NATIVE_WIDGET);
|
||||
#elif XP_WIN
|
||||
mWidget = aWidget; // hold a pointer to this.. not a reference.. because we have to free the dc...
|
||||
nsNativeWidget nativeWidget = aWidget->GetNativeData(NS_NATIVE_GRAPHIC);
|
||||
#else
|
||||
#error Write me!
|
||||
#endif
|
||||
|
||||
Init(aDC, nativeWidget);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesDrawingSurface::Init (nsThebesDeviceContext *aDC, nsNativeWidget aWidget)
|
||||
{
|
||||
mDC = aDC;
|
||||
mNativeWidget = aWidget;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
NS_ASSERTION (GDK_IS_WINDOW(aWidget), "unsupported native widget type!");
|
||||
|
||||
if (!UseGlitz()) {
|
||||
mSurface = new gfxXlibSurface(GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(aWidget)),
|
||||
GDK_WINDOW_XWINDOW(GDK_DRAWABLE(aWidget)),
|
||||
GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(GDK_DRAWABLE(aWidget))));
|
||||
} else {
|
||||
# if defined(MOZ_ENABLE_GLITZ)
|
||||
glitz_surface_t *gsurf;
|
||||
glitz_drawable_t *gdraw;
|
||||
|
||||
glitz_drawable_format_t *gdformat = (glitz_drawable_format_t*) aDC->GetGlitzDrawableFormat();
|
||||
|
||||
Display* dpy = GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(aWidget));
|
||||
Window wnd = GDK_WINDOW_XWINDOW(GDK_DRAWABLE(aWidget));
|
||||
|
||||
Window root_ignore;
|
||||
int x_ignore, y_ignore;
|
||||
unsigned int bwidth_ignore, width, height, depth;
|
||||
|
||||
XGetGeometry(dpy,
|
||||
wnd,
|
||||
&root_ignore, &x_ignore, &y_ignore,
|
||||
&width, &height,
|
||||
&bwidth_ignore, &depth);
|
||||
|
||||
gdraw =
|
||||
glitz_glx_create_drawable_for_window (dpy,
|
||||
DefaultScreen(dpy),
|
||||
gdformat,
|
||||
wnd,
|
||||
width,
|
||||
height);
|
||||
glitz_format_t *gformat =
|
||||
glitz_find_standard_format (gdraw, GLITZ_STANDARD_ARGB32);
|
||||
gsurf =
|
||||
glitz_surface_create (gdraw,
|
||||
gformat,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
NULL);
|
||||
glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR, 0, 0);
|
||||
|
||||
|
||||
//fprintf (stderr, "## nsThebesDrawingSurface::Init Glitz DRAWABLE %p (DC: %p)\n", aWidget, aDC);
|
||||
mSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE);
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
# endif
|
||||
}
|
||||
#elif XP_WIN
|
||||
HDC nativeDC = (HDC)aWidget;
|
||||
mSurface = new gfxWindowsSurface(nativeDC);
|
||||
#else
|
||||
#error write me
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
static nsresult ConvertPixmapsGTK(GdkPixmap* aPmBlack, GdkPixmap* aPmWhite,
|
||||
const nsIntSize& aSize, PRUint8* aData);
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsThebesDrawingSurface::Init (nsThebesDeviceContext *aDC,
|
||||
void* aNativePixmapBlack,
|
||||
void* aNativePixmapWhite,
|
||||
const nsIntSize& aSrcSize)
|
||||
{
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsThebesDrawingSurface::Init aDC %p nativeBlack %p nativeWhite %p size [%d,%d]\n", this, aDC, aNativePixmapBlack, aNativePixmapWhite, aSrcSize.width, aSrcSize.height));
|
||||
|
||||
mWidth = aSrcSize.width;
|
||||
mHeight = aSrcSize.height;
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
nsresult rv;
|
||||
nsRefPtr<gfxImageSurface> imgSurf = new gfxImageSurface(gfxImageSurface::ImageFormatARGB32, mWidth, mHeight);
|
||||
|
||||
GdkPixmap* pmBlack = NS_STATIC_CAST(GdkPixmap*, aNativePixmapBlack);
|
||||
GdkPixmap* pmWhite = NS_STATIC_CAST(GdkPixmap*, aNativePixmapWhite);
|
||||
|
||||
rv = ConvertPixmapsGTK(pmBlack, pmWhite, aSrcSize, imgSurf->Data());
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mSurface = imgSurf;
|
||||
#elif XP_WIN
|
||||
// XXX writeme
|
||||
#else
|
||||
#error Write me!
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesDrawingSurface::PushFilter(const nsIntRect& aRect, PRBool aAreaIsOpaque, float aOpacity)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsThebesDrawingSurface::PopFilter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDrawingSurface::Lock (PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight,
|
||||
void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDrawingSurface::Unlock (void)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDrawingSurface::GetDimensions (PRUint32 *aWidth, PRUint32 *aHeight)
|
||||
{
|
||||
*aWidth = mWidth;
|
||||
*aHeight = mHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDrawingSurface::IsOffscreen(PRBool *aOffScreen)
|
||||
{
|
||||
/* remove this method */
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDrawingSurface::IsPixelAddressable(PRBool *aAddressable)
|
||||
{
|
||||
/* remove this method */
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesDrawingSurface::GetPixelFormat(nsPixelFormat *aFormat)
|
||||
{
|
||||
/* remove this method, and make canvas and DumpToPPM stop using it */
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/***** Platform specific helpers ****/
|
||||
|
||||
/**
|
||||
* Builds an ARGB word from channel values. r,g,b must already
|
||||
* be premultipled/rendered onto black.
|
||||
*/
|
||||
static PRInt32 BuildARGB(PRUint8 aR, PRUint8 aG, PRUint8 aB, PRUint8 aA)
|
||||
{
|
||||
return (aA << 24) | (aR << 16) | (aG << 8) | aB;
|
||||
}
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
static nsresult ConvertPixmapsGTK(GdkPixmap* aPmBlack, GdkPixmap* aPmWhite,
|
||||
const nsIntSize& aSize, PRUint8* aData)
|
||||
{
|
||||
GdkImage *imgBlack = gdk_image_get(aPmBlack, 0, 0,
|
||||
aSize.width,
|
||||
aSize.height);
|
||||
GdkImage *imgWhite = gdk_image_get(aPmWhite, 0, 0,
|
||||
aSize.width,
|
||||
aSize.height);
|
||||
|
||||
if (!imgBlack || !imgWhite)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
PRUint8* blackData = (PRUint8*)GDK_IMAGE_XIMAGE(imgBlack)->data;
|
||||
PRUint8* whiteData = (PRUint8*)GDK_IMAGE_XIMAGE(imgWhite)->data;
|
||||
PRInt32 bpp = GDK_IMAGE_XIMAGE(imgBlack)->bits_per_pixel;
|
||||
PRInt32 stride = GDK_IMAGE_XIMAGE(imgBlack)->bytes_per_line;
|
||||
PRInt32* argb = (PRInt32*)aData;
|
||||
|
||||
if (bpp == 24 || bpp == 32) {
|
||||
PRInt32 pixSize = bpp/8;
|
||||
for (PRInt32 y = 0; y < aSize.height; ++y) {
|
||||
PRUint8* blackRow = blackData + y*stride;
|
||||
PRUint8* whiteRow = whiteData + y*stride;
|
||||
for (PRInt32 x = 0; x < aSize.width; ++x) {
|
||||
PRUint8 alpha = 0;
|
||||
if (blackRow[0] == whiteRow[0] &&
|
||||
blackRow[1] == whiteRow[1] &&
|
||||
blackRow[2] == whiteRow[2]) {
|
||||
alpha = 0xFF;
|
||||
}
|
||||
*argb++ = BuildARGB(blackRow[2], blackRow[1],
|
||||
blackRow[0], alpha);
|
||||
blackRow += pixSize;
|
||||
whiteRow += pixSize;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NS_ERROR("Unhandled bpp!");
|
||||
}
|
||||
|
||||
gdk_image_unref(imgBlack);
|
||||
gdk_image_unref(imgWhite);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRBool
|
||||
nsThebesDrawingSurface::UseGlitz()
|
||||
{
|
||||
#ifdef MOZ_ENABLE_GLITZ
|
||||
if (mGlitzMode == -1) {
|
||||
if (getenv("MOZ_GLITZ")) {
|
||||
glitz_glx_init (NULL);
|
||||
mGlitzMode = 1;
|
||||
} else {
|
||||
mGlitzMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mGlitzMode)
|
||||
return PR_TRUE;
|
||||
|
||||
#endif
|
||||
return PR_FALSE;
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _NSTHEBESDRAWINGSURFACE_H_
|
||||
#define _NSTHEBESDRAWINGSURFACE_H_
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsSize.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsIDrawingSurface.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
|
||||
class nsThebesDeviceContext;
|
||||
|
||||
class nsThebesDrawingSurface : public nsIDrawingSurface
|
||||
{
|
||||
public:
|
||||
nsThebesDrawingSurface ();
|
||||
virtual ~nsThebesDrawingSurface ();
|
||||
|
||||
// create a image surface if aFastAccess == TRUE, otherwise create
|
||||
// a fast server pixmap
|
||||
nsresult Init (nsThebesDeviceContext *aDC, PRUint32 aWidth, PRUint32 aHeight, PRBool aFastAccess);
|
||||
|
||||
// create a fast drawing surface for a native widget
|
||||
nsresult Init (nsThebesDeviceContext *aDC, nsIWidget *aWidget);
|
||||
|
||||
// create a fast drawing surface for a native widget
|
||||
nsresult Init (nsThebesDeviceContext *aDC, nsNativeWidget aWidget);
|
||||
|
||||
// create a drawing surface for a native pixmap
|
||||
nsresult Init (nsThebesDeviceContext* aDC, void* aNativePixmapBlack,
|
||||
void* aNativePixmapWhite,
|
||||
const nsIntSize& aSize);
|
||||
|
||||
// nsISupports interface
|
||||
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);
|
||||
|
||||
/* utility functions */
|
||||
gfxASurface *GetThebesSurface(void) { return mSurface; }
|
||||
PRInt32 GetDepth() { /* XXX */ return 24; }
|
||||
nsNativeWidget GetNativeWidget(void) { return mNativeWidget; }
|
||||
|
||||
nsresult PushFilter(const nsIntRect& aRect, PRBool aAreaIsOpaque, float aOpacity);
|
||||
void PopFilter();
|
||||
|
||||
static PRBool UseGlitz();
|
||||
static PRInt32 mGlitzMode;
|
||||
private:
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsThebesDeviceContext *mDC;
|
||||
nsNativeWidget mNativeWidget;
|
||||
#ifdef XP_WIN
|
||||
nsIWidget *mWidget;
|
||||
#endif
|
||||
|
||||
PRUint32 mWidth, mHeight;
|
||||
};
|
||||
|
||||
#endif /* _NSTHEBESDRAWINGSURFACE_H_ */
|
|
@ -0,0 +1,383 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
*
|
||||
* 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 "nsThebesFontMetrics.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#define FONT_FILE "Vera.ttf"
|
||||
#define FONT_SIZE 10
|
||||
/*
|
||||
#define FONT_FILE "verdana.ttf"
|
||||
#define FONT_SIZE 12
|
||||
*/
|
||||
|
||||
#define FT_FLOOR(X) ((X & -64) >> 6)
|
||||
#define FT_CEIL(X) (((X + 63) & -64) >> 6)
|
||||
|
||||
static FT_Library ftlib = nsnull;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesFontMetrics, nsIFontMetrics)
|
||||
|
||||
nsThebesFontMetrics::nsThebesFontMetrics() :
|
||||
mMaxAscent(0),
|
||||
mMaxDescent(0),
|
||||
mMaxAdvance(0),
|
||||
mUnderlineOffset(0),
|
||||
mUnderlineHeight(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
if (!ftlib) {
|
||||
FT_Init_FreeType(&ftlib);
|
||||
}
|
||||
}
|
||||
|
||||
nsThebesFontMetrics::~nsThebesFontMetrics()
|
||||
{
|
||||
FT_Done_Face(mFace);
|
||||
}
|
||||
|
||||
static char *
|
||||
GetFontPath()
|
||||
{
|
||||
return strdup("/tmp/fonts/" FONT_FILE);
|
||||
|
||||
nsCOMPtr<nsIFile> aFile;
|
||||
NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(aFile));
|
||||
aFile->Append(NS_LITERAL_STRING(FONT_FILE));
|
||||
nsAutoString pathBuf;
|
||||
aFile->GetPath(pathBuf);
|
||||
NS_LossyConvertUCS2toASCII pathCBuf(pathBuf);
|
||||
|
||||
return strdup(pathCBuf.get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||
nsIDeviceContext *aContext)
|
||||
{
|
||||
mFont = aFont;
|
||||
mLangGroup = aLangGroup;
|
||||
|
||||
mDeviceContext = aContext;
|
||||
mDev2App = 1.0;
|
||||
|
||||
char *fontPath = GetFontPath();
|
||||
FT_Error ferr = FT_New_Face(ftlib, fontPath, 0, &mFace);
|
||||
if (ferr != 0) {
|
||||
fprintf (stderr, "FT Error: %d\n", ferr);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
free(fontPath);
|
||||
|
||||
FT_Set_Char_Size(mFace, 0, FONT_SIZE << 6, 72, 72);
|
||||
|
||||
mMaxAscent = mFace->bbox.yMax;
|
||||
mMaxDescent = mFace->bbox.yMin;
|
||||
mMaxAdvance = mFace->max_advance_width;
|
||||
|
||||
mUnderlineOffset = mFace->underline_position;
|
||||
mUnderlineHeight = mFace->underline_thickness;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::Destroy()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetXHeight(nscoord& aResult)
|
||||
{
|
||||
aResult = NSToCoordRound(14 * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetSuperscriptOffset(nscoord& aResult)
|
||||
{
|
||||
aResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetSubscriptOffset(nscoord& aResult)
|
||||
{
|
||||
aResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetStrikeout(nscoord& aOffset, nscoord& aSize)
|
||||
{
|
||||
aOffset = 0;
|
||||
aSize = NSToCoordRound(1 * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetUnderline(nscoord& aOffset, nscoord& aSize)
|
||||
{
|
||||
const FT_Fixed scale = mFace->size->metrics.y_scale;
|
||||
|
||||
aOffset = FT_FLOOR(FT_MulFix(mUnderlineOffset, scale));
|
||||
aOffset = NSToCoordRound(aOffset * mDev2App);
|
||||
|
||||
aSize = FT_CEIL(FT_MulFix(mUnderlineHeight, scale));
|
||||
if (aSize > 1)
|
||||
aSize = 1;
|
||||
aSize = NSToCoordRound(aSize * mDev2App);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetHeight(nscoord &aHeight)
|
||||
{
|
||||
aHeight = NSToCoordRound((mFace->size->metrics.height >> 6) * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetInternalLeading(nscoord &aLeading)
|
||||
{
|
||||
// aLeading = 0 * mDev2App;
|
||||
aLeading = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetExternalLeading(nscoord &aLeading)
|
||||
{
|
||||
// aLeading = 0 * mDev2App;
|
||||
aLeading = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetEmHeight(nscoord &aHeight)
|
||||
{
|
||||
/* ascent + descent */
|
||||
#if FONT_SIZE == 10
|
||||
const nscoord emHeight = 10;
|
||||
#else
|
||||
/* XXX this is for 12px verdana ... */
|
||||
const nscoord emHeight = 14;
|
||||
#endif
|
||||
|
||||
aHeight = NSToCoordRound(emHeight * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetEmAscent(nscoord &aAscent)
|
||||
{
|
||||
/* units above the base line */
|
||||
#if FONT_SIZE == 10
|
||||
const nscoord emAscent = 10;
|
||||
#else
|
||||
/* XXX this is for 12px verdana ... */
|
||||
const nscoord emAscent = 12;
|
||||
#endif
|
||||
aAscent = NSToCoordRound(emAscent * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetEmDescent(nscoord &aDescent)
|
||||
{
|
||||
/* units below the base line */
|
||||
#if FONT_SIZE == 10
|
||||
const nscoord emDescent = 0;
|
||||
#else
|
||||
/* XXX this is for 12px verdana ... */
|
||||
const nscoord emDescent = 2;
|
||||
#endif
|
||||
aDescent = NSToCoordRound(emDescent * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetMaxHeight(nscoord &aHeight)
|
||||
{
|
||||
/* ascent + descent */
|
||||
aHeight = FT_CEIL(FT_MulFix(mMaxAscent, mFace->size->metrics.y_scale))
|
||||
- FT_CEIL(FT_MulFix(mMaxDescent, mFace->size->metrics.y_scale))
|
||||
+ 1;
|
||||
|
||||
aHeight = NSToCoordRound(aHeight * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetMaxAscent(nscoord &aAscent)
|
||||
{
|
||||
/* units above the base line */
|
||||
aAscent = FT_CEIL(FT_MulFix(mMaxAscent, mFace->size->metrics.y_scale));
|
||||
aAscent = NSToCoordRound(aAscent * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetMaxDescent(nscoord &aDescent)
|
||||
{
|
||||
/* units below the base line */
|
||||
aDescent = -FT_CEIL(FT_MulFix(mMaxDescent, mFace->size->metrics.y_scale));
|
||||
aDescent = NSToCoordRound(aDescent * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetMaxAdvance(nscoord &aAdvance)
|
||||
{
|
||||
aAdvance = FT_CEIL(FT_MulFix(mMaxAdvance, mFace->size->metrics.x_scale));
|
||||
aAdvance = NSToCoordRound(aAdvance * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetLangGroup(nsIAtom** aLangGroup)
|
||||
{
|
||||
*aLangGroup = mLangGroup;
|
||||
NS_IF_ADDREF(*aLangGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetFontHandle(nsFontHandle &aHandle)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetAveCharWidth(nscoord& aAveCharWidth)
|
||||
{
|
||||
aAveCharWidth = NSToCoordRound(7 * mDev2App);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetSpaceWidth(nscoord& aSpaceCharWidth)
|
||||
{
|
||||
FT_Load_Char(mFace, ' ', FT_LOAD_DEFAULT | FT_LOAD_NO_AUTOHINT);
|
||||
|
||||
aSpaceCharWidth = NSToCoordRound((mFace->glyph->advance.x >> 6) * mDev2App);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsThebesFontMetrics::MeasureString(const char *aString, PRUint32 aLength)
|
||||
{
|
||||
nscoord width = 0;
|
||||
PRUint32 i;
|
||||
int error;
|
||||
|
||||
FT_UInt glyph_index;
|
||||
FT_UInt previous = 0;
|
||||
|
||||
for (i=0; i < aLength; ++i) {
|
||||
glyph_index = FT_Get_Char_Index(mFace, aString[i]);
|
||||
/*
|
||||
if (previous && glyph_index) {
|
||||
FT_Vector delta;
|
||||
FT_Get_Kerning(mFace, previous, glyph_index,
|
||||
FT_KERNING_DEFAULT, &delta);
|
||||
width += delta.x >> 6;
|
||||
}
|
||||
*/
|
||||
error = FT_Load_Glyph(mFace, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_NO_AUTOHINT);
|
||||
if (error)
|
||||
continue;
|
||||
|
||||
width += mFace->glyph->advance.x;
|
||||
previous = glyph_index;
|
||||
}
|
||||
|
||||
return NSToCoordRound((width >> 6) * mDev2App);
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsThebesFontMetrics::MeasureString(const PRUnichar *aString, PRUint32 aLength)
|
||||
{
|
||||
nscoord width = 0;
|
||||
PRUint32 i;
|
||||
int error;
|
||||
|
||||
FT_UInt glyph_index;
|
||||
FT_UInt previous = 0;
|
||||
|
||||
for (i=0; i < aLength; ++i) {
|
||||
glyph_index = FT_Get_Char_Index(mFace, aString[i]);
|
||||
/*
|
||||
if (previous && glyph_index) {
|
||||
FT_Vector delta;
|
||||
FT_Get_Kerning(mFace, previous, glyph_index,
|
||||
FT_KERNING_DEFAULT, &delta);
|
||||
width += delta.x >> 6;
|
||||
}
|
||||
*/
|
||||
error = FT_Load_Glyph(mFace, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_NO_AUTOHINT);
|
||||
if (error)
|
||||
continue;
|
||||
|
||||
width += mFace->glyph->advance.x;
|
||||
previous = glyph_index;
|
||||
}
|
||||
|
||||
return NSToCoordRound((width >> 6) * mDev2App);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetLeading(nscoord& aLeading)
|
||||
{
|
||||
aLeading = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetNormalLineHeight(nscoord& aLineHeight)
|
||||
{
|
||||
aLineHeight = 10;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 NSTHEBESFONTMETRICS__H__
|
||||
#define NSTHEBESFONTMETRICS__H__
|
||||
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
class nsThebesFontMetrics : public nsIFontMetrics
|
||||
{
|
||||
public:
|
||||
nsThebesFontMetrics();
|
||||
virtual ~nsThebesFontMetrics();
|
||||
|
||||
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 GetInternalLeading(nscoord &aLeading);
|
||||
NS_IMETHOD GetExternalLeading(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 GetLangGroup(nsIAtom** aLangGroup);
|
||||
NS_IMETHOD GetFontHandle(nsFontHandle &aHandle);
|
||||
NS_IMETHOD GetAveCharWidth(nscoord& aAveCharWidth);
|
||||
NS_IMETHOD GetSpaceWidth(nscoord& aSpaceCharWidth);
|
||||
NS_IMETHOD GetLeading(nscoord& aLeading);
|
||||
NS_IMETHOD GetNormalLineHeight(nscoord& aLineHeight);
|
||||
|
||||
/* local methods */
|
||||
nscoord MeasureString(const char *aString, PRUint32 aLength);
|
||||
nscoord MeasureString(const PRUnichar *aString, PRUint32 aLength);
|
||||
|
||||
private:
|
||||
FT_Face mFace;
|
||||
nsCOMPtr<nsIDeviceContext> mDeviceContext;
|
||||
nsCOMPtr<nsIAtom> mLangGroup;
|
||||
float mDev2App;
|
||||
|
||||
long mMaxAscent;
|
||||
long mMaxDescent;
|
||||
short mMaxAdvance;
|
||||
|
||||
long mUnderlineOffset;
|
||||
long mUnderlineHeight;
|
||||
};
|
||||
|
||||
#endif /* NSTHEBESFONTMETRICS__H__ */
|
|
@ -0,0 +1,166 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "nsScriptableRegion.h"
|
||||
#include "gfxImageFrame.h"
|
||||
|
||||
#include "nsThebesDeviceContext.h"
|
||||
#include "nsThebesRenderingContext.h"
|
||||
#include "nsThebesImage.h"
|
||||
#include "nsThebesRegion.h"
|
||||
#include "nsThebesScreen.h"
|
||||
#include "nsThebesScreenManager.h"
|
||||
#include "nsThebesBlender.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_PANGO
|
||||
#include "nsFontMetricsPango.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontMetricsPango)
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
#include "nsFontMetricsWin2.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontMetricsWin)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesBlender)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(gfxImageFrame)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesDeviceContext)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRenderingContext)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesImage)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRegion)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesScreenManager)
|
||||
|
||||
static NS_IMETHODIMP nsScriptableRegionConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsIScriptableRegion *inst = nsnull;
|
||||
|
||||
if ( !aResult )
|
||||
{
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
return rv;
|
||||
}
|
||||
*aResult = nsnull;
|
||||
if (aOuter)
|
||||
{
|
||||
rv = NS_ERROR_NO_AGGREGATION;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr <nsIRegion> rgn;
|
||||
NS_NEWXPCOM(rgn, nsThebesRegion);
|
||||
nsCOMPtr<nsIScriptableRegion> 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[] =
|
||||
{
|
||||
{ "Thebes nsFontMetrics",
|
||||
NS_FONT_METRICS_CID,
|
||||
"@mozilla.org/gfx/fontmetrics;1",
|
||||
#ifdef MOZ_ENABLE_PANGO
|
||||
nsFontMetricsPangoConstructor
|
||||
#elif XP_WIN
|
||||
nsFontMetricsWinConstructor
|
||||
#else
|
||||
#error write me!
|
||||
#endif
|
||||
},
|
||||
{ "Thebes Device Context",
|
||||
NS_DEVICE_CONTEXT_CID,
|
||||
"@mozilla.org/gfx/devicecontext;1",
|
||||
nsThebesDeviceContextConstructor },
|
||||
{ "Thebes Rendering Context",
|
||||
NS_RENDERING_CONTEXT_CID,
|
||||
"@mozilla.org/gfx/renderingcontext;1",
|
||||
nsThebesRenderingContextConstructor },
|
||||
{ "Thebes nsImage",
|
||||
NS_IMAGE_CID,
|
||||
"@mozilla.org/gfx/image;1",
|
||||
nsThebesImageConstructor },
|
||||
{ "Thebes Region",
|
||||
NS_REGION_CID,
|
||||
"@mozilla.org/gfx/region/nsThebes;1",
|
||||
nsThebesRegionConstructor },
|
||||
{ "Thebes Screen Manager",
|
||||
NS_SCREENMANAGER_CID,
|
||||
"@mozilla.org/gfx/screenmanager;1",
|
||||
nsThebesScreenManagerConstructor },
|
||||
{ "Scriptable Region",
|
||||
NS_SCRIPTABLE_REGION_CID,
|
||||
"@mozilla.org/gfx/region;1",
|
||||
nsScriptableRegionConstructor },
|
||||
{ "Thebes Blender",
|
||||
NS_BLENDER_CID,
|
||||
"@mozilla.org/gfx/blender;1",
|
||||
nsThebesBlenderConstructor },
|
||||
{ "image frame",
|
||||
GFX_IMAGEFRAME_CID,
|
||||
"@mozilla.org/gfx/image/frame;2",
|
||||
gfxImageFrameConstructor, }
|
||||
};
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
nsThebesGfxModuleDtor(nsIModule *self)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_NSGETMODULE_WITH_DTOR(nsGfxModule, components, nsThebesGfxModuleDtor)
|
||||
|
|
@ -0,0 +1,643 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 "nsMemory.h"
|
||||
#include "nsColor.h"
|
||||
|
||||
#include "nsThebesDeviceContext.h"
|
||||
#include "nsThebesRenderingContext.h"
|
||||
#include "nsThebesDrawingSurface.h"
|
||||
#include "nsThebesImage.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPattern.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
#include <gdk/gdkx.h>
|
||||
#include "gfxXlibSurface.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_GLITZ
|
||||
#include "glitz-glx.h"
|
||||
#include "gfxGlitzSurface.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static PRUint8 Unpremultiply(PRUint8 aVal, PRUint8 aAlpha);
|
||||
static void ARGBToThreeChannel(PRUint32* aARGB, PRUint8* aData);
|
||||
static PRUint8 Premultiply(PRUint8 aVal, PRUint8 aAlpha);
|
||||
static PRUint32 ThreeChannelToARGB(PRUint8* aData, PRUint8 aAlpha);
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesImage, nsIImage)
|
||||
|
||||
nsThebesImage::nsThebesImage()
|
||||
: mWidth(0),
|
||||
mHeight(0),
|
||||
mDecoded(0,0,0,0),
|
||||
mLockedData(nsnull),
|
||||
mLockedAlpha(nsnull),
|
||||
mAlphaDepth(0),
|
||||
mLocked(PR_FALSE),
|
||||
mHadAnyData(PR_FALSE),
|
||||
mUpToDate(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
|
||||
{
|
||||
NS_ASSERTION(aDepth == 24, "nsThebesImage::Init called with depth != 24");
|
||||
|
||||
gfxImageSurface::gfxImageFormat format;
|
||||
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
|
||||
switch(aMaskRequirements)
|
||||
{
|
||||
case nsMaskRequirements_kNeeds1Bit:
|
||||
mAlphaDepth = 1;
|
||||
format = gfxImageSurface::ImageFormatARGB32;
|
||||
break;
|
||||
case nsMaskRequirements_kNeeds8Bit:
|
||||
mAlphaDepth = 8;
|
||||
format = gfxImageSurface::ImageFormatARGB32;
|
||||
break;
|
||||
default:
|
||||
mAlphaDepth = 0;
|
||||
format = gfxImageSurface::ImageFormatARGB32;
|
||||
break;
|
||||
}
|
||||
|
||||
mImageSurface = new gfxImageSurface (format, mWidth, mHeight);
|
||||
memset(mImageSurface->Data(), 0xFF, mHeight * mImageSurface->Stride());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsThebesImage::~nsThebesImage()
|
||||
{
|
||||
if (mLockedData)
|
||||
nsMemory::Free(mLockedData);
|
||||
if (mLockedAlpha)
|
||||
nsMemory::Free(mLockedAlpha);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetBytesPix()
|
||||
{
|
||||
// not including alpha
|
||||
return 3;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetIsRowOrderTopToBottom()
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetWidth()
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetHeight()
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
PRUint8 *
|
||||
nsThebesImage::GetBits()
|
||||
{
|
||||
//NS_ASSERTION(mLocked == PR_TRUE, "GetBits called outside of Lock!");
|
||||
return mLockedData;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetLineStride()
|
||||
{
|
||||
return mWidth * 3;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetHasAlphaMask()
|
||||
{
|
||||
return mAlphaDepth > 0;
|
||||
}
|
||||
|
||||
PRUint8 *
|
||||
nsThebesImage::GetAlphaBits()
|
||||
{
|
||||
//NS_ASSERTION(mLocked == PR_TRUE, "GetAlphaBits called outside of Lock!");
|
||||
return (PRUint8 *) mLockedAlpha;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetAlphaLineStride()
|
||||
{
|
||||
return mAlphaDepth == 1 ? (mWidth+7)/8 : mWidth;
|
||||
}
|
||||
|
||||
void
|
||||
nsThebesImage::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect)
|
||||
{
|
||||
mDecoded.UnionRect(mDecoded, *aUpdateRect);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetIsImageComplete()
|
||||
{
|
||||
return mDecoded == nsRect(0, 0, mWidth, mHeight);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Optimize(nsIDeviceContext* aContext)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
|
||||
if (!mOptSurface) {
|
||||
#ifdef MOZ_ENABLE_GTK2
|
||||
if (!nsThebesDrawingSurface::UseGlitz()) {
|
||||
XRenderPictFormat *fmt = nsnull;
|
||||
|
||||
if (mRealAlphaDepth == 0) {
|
||||
fmt = gfxXlibSurface::FindRenderFormat(GDK_DISPLAY(), gfxASurface::ImageFormatRGB24);
|
||||
} else if (mRealAlphaDepth == 1) {
|
||||
fmt = gfxXlibSurface::FindRenderFormat(GDK_DISPLAY(), gfxASurface::ImageFormatARGB32);
|
||||
} else if (mRealAlphaDepth == 8) {
|
||||
fmt = gfxXlibSurface::FindRenderFormat(GDK_DISPLAY(), gfxASurface::ImageFormatARGB32);
|
||||
}
|
||||
|
||||
/* XXX handle mRealAlphaDepth = 1, and create separate mask */
|
||||
|
||||
if (fmt) {
|
||||
mOptSurface = new gfxXlibSurface(GDK_DISPLAY(),
|
||||
fmt,
|
||||
mWidth, mHeight);
|
||||
}
|
||||
} else {
|
||||
# ifdef MOZ_ENABLE_GLITZ
|
||||
// glitz
|
||||
nsThebesDeviceContext *tdc = NS_STATIC_CAST(nsThebesDeviceContext*, aContext);
|
||||
glitz_drawable_format_t *gdf = (glitz_drawable_format_t*) tdc->GetGlitzDrawableFormat();
|
||||
glitz_drawable_t *gdraw = glitz_glx_create_pbuffer_drawable (GDK_DISPLAY(),
|
||||
DefaultScreen(GDK_DISPLAY()),
|
||||
gdf,
|
||||
mWidth, mHeight);
|
||||
glitz_format_t *gf =
|
||||
glitz_find_standard_format (gdraw, GLITZ_STANDARD_ARGB32);
|
||||
glitz_surface_t *gsurf =
|
||||
glitz_surface_create (gdraw,
|
||||
gf,
|
||||
mWidth,
|
||||
mHeight,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR, 0, 0);
|
||||
mOptSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mOptSurface) {
|
||||
nsRefPtr<gfxContext> tmpCtx(new gfxContext(mOptSurface));
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->SetSource(mImageSurface);
|
||||
#if 0
|
||||
PRUint32 k = (PRUint32) this;
|
||||
k |= 0xff000000;
|
||||
tmpCtx->SetColor(gfxRGBA(nscolor(k)));
|
||||
#endif
|
||||
tmpCtx->Paint();
|
||||
#if 0
|
||||
tmpCtx->NewPath();
|
||||
tmpCtx->Rectangle(gfxRect(0, 0, mWidth, mHeight));
|
||||
tmpCtx->Fill();
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsColorMap *
|
||||
nsThebesImage::GetColorMap()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRInt8
|
||||
nsThebesImage::GetAlphaDepth()
|
||||
{
|
||||
return mAlphaDepth;
|
||||
}
|
||||
|
||||
void *
|
||||
nsThebesImage::GetBitInfo()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::LockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
//NS_ASSERTION(!mLocked, "LockImagePixels called on already locked image!");
|
||||
PRUint32 tmpSize;
|
||||
|
||||
// if we already have locked data allocated,
|
||||
// and we have some data, and we're not up to date,
|
||||
// then don't bother updating frmo the image surface
|
||||
// to the 2 buffers -- the 2 buffers are more current,
|
||||
// because UpdateFromLockedData() hasn't been called yet.
|
||||
//
|
||||
// UpdateFromLockedData() is only called right before we
|
||||
// actually try to draw, because the image decoders
|
||||
// will call Lock/Unlock pretty frequently as they decode
|
||||
// rows of the image.
|
||||
|
||||
if (mLockedData && mHadAnyData && !mUpToDate)
|
||||
return NS_OK;
|
||||
|
||||
if (mAlphaDepth > 0) {
|
||||
NS_ASSERTION(mAlphaDepth == 1 || mAlphaDepth == 8,
|
||||
"Bad alpha depth");
|
||||
tmpSize = mHeight*(mAlphaDepth == 1 ? ((mWidth+7)/8) : mWidth);
|
||||
if (!mLockedAlpha)
|
||||
mLockedAlpha = (PRUint8*)nsMemory::Alloc(tmpSize);
|
||||
if (!mLockedAlpha)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
tmpSize = mWidth * mHeight * 3;
|
||||
if (!mLockedData)
|
||||
mLockedData = (PRUint8*)nsMemory::Alloc(tmpSize);
|
||||
if (!mLockedData)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (mAlphaDepth > 0 && mHadAnyData) {
|
||||
// fill from existing ARGB buffer
|
||||
if (mAlphaDepth == 8) {
|
||||
PRInt32 destCount = 0;
|
||||
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32* srcRow = (PRUint32*) (mImageSurface->Data() + (mImageSurface->Stride()*row));
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
mLockedAlpha[destCount++] = (PRUint8)(srcRow[col] >> 24);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PRInt32 i = 0;
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32* srcRow = (PRUint32*) (mImageSurface->Data() + (mImageSurface->Stride()*row));
|
||||
PRUint8 alphaBits = 0;
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
PRUint8 mask = 1 << (7 - (col&7));
|
||||
|
||||
if (srcRow[col] & 0xFF000000) {
|
||||
alphaBits |= mask;
|
||||
}
|
||||
if (mask == 0x01) {
|
||||
// This mask byte is complete, write it back
|
||||
mLockedAlpha[i] = alphaBits;
|
||||
alphaBits = 0;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (mWidth & 7) {
|
||||
// write back the incomplete alpha mask
|
||||
mLockedAlpha[i] = alphaBits;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mHadAnyData) {
|
||||
int destCount = 0;
|
||||
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32* srcRow = (PRUint32*) (mImageSurface->Data() + (mImageSurface->Stride()*row));
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
ARGBToThreeChannel(&srcRow[col], &mLockedData[destCount*3]);
|
||||
destCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mLocked = PR_TRUE;
|
||||
|
||||
mOptSurface = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::UnlockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
//NS_ASSERTION(mLocked, "UnlockImagePixels called on unlocked image!");
|
||||
|
||||
mLocked = PR_FALSE;
|
||||
mUpToDate = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsThebesImage::UpdateFromLockedData()
|
||||
{
|
||||
if (!mLockedData || mUpToDate)
|
||||
return;
|
||||
|
||||
mUpToDate = PR_TRUE;
|
||||
|
||||
NS_ASSERTION(mAlphaDepth == 0 || mAlphaDepth == 1 || mAlphaDepth == 8,
|
||||
"Bad alpha depth");
|
||||
|
||||
mRealAlphaDepth = 0;
|
||||
|
||||
PRInt32 alphaIndex = 0;
|
||||
PRInt32 lockedBufIndex = 0;
|
||||
for (PRInt32 row = 0; row < mHeight; ++row) {
|
||||
PRUint32 *destPtr = (PRUint32*) (mImageSurface->Data() + (row * mImageSurface->Stride()));
|
||||
|
||||
for (PRInt32 col = 0; col < mWidth; ++col) {
|
||||
PRUint8 alpha = 0xFF;
|
||||
|
||||
if (mAlphaDepth == 1) {
|
||||
PRUint8 mask = 1 << (7 - (col&7));
|
||||
if (!(mLockedAlpha[alphaIndex] & mask)) {
|
||||
alpha = 0;
|
||||
}
|
||||
if (mask == 0x01) {
|
||||
++alphaIndex;
|
||||
}
|
||||
} else if (mAlphaDepth == 8) {
|
||||
alpha = mLockedAlpha[lockedBufIndex];
|
||||
}
|
||||
|
||||
if (mRealAlphaDepth == 0 && alpha != 0xff)
|
||||
mRealAlphaDepth = mAlphaDepth;
|
||||
|
||||
*destPtr++ =
|
||||
ThreeChannelToARGB(&mLockedData[lockedBufIndex*3], alpha);
|
||||
|
||||
++lockedBufIndex;
|
||||
}
|
||||
if (mAlphaDepth == 1) {
|
||||
if (mWidth & 7) {
|
||||
++alphaIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PR_FALSE) { // Enabling this saves memory but can lead to pathologically bad
|
||||
// performance. Would also cause problems with premultiply/unpremultiply too
|
||||
nsMemory::Free(mLockedData);
|
||||
mLockedData = nsnull;
|
||||
if (mLockedAlpha) {
|
||||
nsMemory::Free(mLockedAlpha);
|
||||
mLockedAlpha = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
mHadAnyData = PR_TRUE;
|
||||
}
|
||||
|
||||
/* NB: These are pixels, not twips. */
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface,
|
||||
PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return Draw(aContext, aSurface, 0, 0, mWidth, mHeight, aX, aY, aWidth, aHeight);
|
||||
}
|
||||
|
||||
/* NB: These are pixels, not twips. */
|
||||
/* BUT nsRenderingContextImpl's DrawImage calls this with twips. */
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
|
||||
nsThebesRenderingContext *thebesRC = NS_STATIC_CAST(nsThebesRenderingContext*, &aContext);
|
||||
gfxContext *ctx = thebesRC->Thebes();
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "nsThebesImage::Draw src [%d %d %d %d] dest [%d %d %d %d] tx [%f %f]\n",
|
||||
aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth, aDHeight,
|
||||
ctx->CurrentMatrix().GetTranslation().x, ctx->CurrentMatrix().GetTranslation().y);
|
||||
#endif
|
||||
|
||||
gfxRect sr(aSX, aSY, aSWidth, aSHeight);
|
||||
gfxRect dr(aDX, aDY, aDWidth, aDHeight);
|
||||
|
||||
gfxMatrix mat;
|
||||
mat.Translate(gfxPoint(aSX, aSY));
|
||||
mat.Scale(double(aSWidth)/aDWidth, double(aSHeight)/aDHeight);
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(ThebesSurface());
|
||||
pat->SetMatrix(mat);
|
||||
|
||||
ctx->NewPath();
|
||||
ctx->PixelSnappedRectangleAndSetPattern(dr, pat);
|
||||
ctx->Fill();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* DrawTile is always relative to the device; never relative to the current
|
||||
* transformation matrix on the device. This is where the IdentityMatrix() bits
|
||||
* come from.
|
||||
*/
|
||||
/* NB: Still pixels! */
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::DrawTile(nsIRenderingContext &aContext,
|
||||
nsIDrawingSurface *aSurface,
|
||||
PRInt32 aSXOffset, PRInt32 aSYOffset,
|
||||
PRInt32 aPadX, PRInt32 aPadY,
|
||||
const nsRect &aTileRect)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
|
||||
nsThebesRenderingContext *thebesRC = NS_STATIC_CAST(nsThebesRenderingContext*, &aContext);
|
||||
gfxContext *ctx = thebesRC->Thebes();
|
||||
|
||||
if (aTileRect.width <= 0 || aTileRect.height <= 0)
|
||||
return NS_OK;
|
||||
|
||||
if (aPadX || aPadY)
|
||||
fprintf (stderr, "Warning: nsThebesImage::DrawTile given padX(%d)/padY(%d), ignoring\n", aPadX, aPadY);
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "****** nsThebesImage::DrawTile: (%d,%d [%d, %d]) -> (%d,%d,%d,%d)\n",
|
||||
aSXOffset, aSYOffset, mWidth, mHeight,
|
||||
aTileRect.x, aTileRect.y,
|
||||
aTileRect.width, aTileRect.height);
|
||||
#endif
|
||||
|
||||
gfxMatrix savedMatrix = ctx->CurrentMatrix();
|
||||
PRBool reallyRepeating = PR_TRUE;
|
||||
|
||||
/* Let's figure out if this really is repeating, or if we're just drawing a subrect */
|
||||
if (aTileRect.x + aTileRect.width > mWidth ||
|
||||
aTileRect.y + aTileRect.height > mHeight)
|
||||
{
|
||||
reallyRepeating = PR_TRUE;
|
||||
}
|
||||
|
||||
ctx->IdentityMatrix();
|
||||
|
||||
PRInt32 x0 = aTileRect.x - aSXOffset;
|
||||
PRInt32 y0 = aTileRect.y - aSYOffset;
|
||||
|
||||
ctx->Translate(gfxPoint(x0, y0));
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(ThebesSurface());
|
||||
if (reallyRepeating)
|
||||
pat->SetExtend(CAIRO_EXTEND_REPEAT);
|
||||
|
||||
ctx->NewPath();
|
||||
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(aSXOffset, aSYOffset,
|
||||
aTileRect.width, aTileRect.height),
|
||||
pat);
|
||||
ctx->Fill();
|
||||
|
||||
ctx->SetMatrix(savedMatrix);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* This is only used by the GIF decoder, via gfxImageFrame::DrawTo */
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
UpdateFromLockedData();
|
||||
|
||||
nsThebesImage *dstThebesImage = NS_STATIC_CAST(nsThebesImage*, aDstImage);
|
||||
|
||||
nsRefPtr<gfxContext> dst = new gfxContext(dstThebesImage->ThebesSurface());
|
||||
|
||||
dst->NewPath();
|
||||
// We don't use PixelSnappedRectangleAndSetPattern because if
|
||||
// these coords aren't already pixel aligned, we've lost
|
||||
// before we've even begun.
|
||||
dst->Translate(gfxPoint(aDX, aDY));
|
||||
dst->Rectangle(gfxRect(0, 0, aDWidth, aDHeight), PR_TRUE);
|
||||
dst->Scale(double(aDWidth)/mWidth, double(aDHeight)/mHeight);
|
||||
|
||||
dst->SetSource(ThebesSurface());
|
||||
dst->Fill();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** Image conversion utils **/
|
||||
|
||||
static PRUint8 Unpremultiply(PRUint8 aVal, PRUint8 aAlpha) {
|
||||
return (aVal*255)/aAlpha;
|
||||
}
|
||||
|
||||
static void ARGBToThreeChannel(PRUint32* aARGB, PRUint8* aData) {
|
||||
PRUint8 a = (PRUint8)(*aARGB >> 24);
|
||||
PRUint8 r = (PRUint8)(*aARGB >> 16);
|
||||
PRUint8 g = (PRUint8)(*aARGB >> 8);
|
||||
PRUint8 b = (PRUint8)(*aARGB >> 0);
|
||||
|
||||
if (a != 0xFF) {
|
||||
if (a == 0) {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
} else {
|
||||
r = Unpremultiply(r, a);
|
||||
g = Unpremultiply(g, a);
|
||||
b = Unpremultiply(b, a);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||
// BGR format; assume little-endian system
|
||||
#ifndef IS_LITTLE_ENDIAN
|
||||
#error Strange big-endian/OS combination
|
||||
#endif
|
||||
// BGR, blue byte first
|
||||
aData[0] = b; aData[1] = g; aData[2] = r;
|
||||
#else
|
||||
// RGB, red byte first
|
||||
aData[0] = r; aData[1] = g; aData[2] = b;
|
||||
#endif
|
||||
}
|
||||
|
||||
static PRUint8 Premultiply(PRUint8 aVal, PRUint8 aAlpha) {
|
||||
PRUint32 r;
|
||||
FAST_DIVIDE_BY_255(r, aVal*aAlpha);
|
||||
return (PRUint8)r;
|
||||
}
|
||||
|
||||
static PRUint32 ThreeChannelToARGB(PRUint8* aData, PRUint8 aAlpha) {
|
||||
PRUint8 r, g, b;
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||
// BGR format; assume little-endian system
|
||||
#ifndef IS_LITTLE_ENDIAN
|
||||
#error Strange big-endian/OS combination
|
||||
#endif
|
||||
// BGR, blue byte first
|
||||
b = aData[0]; g = aData[1]; r = aData[2];
|
||||
#else
|
||||
// RGB, red byte first
|
||||
r = aData[0]; g = aData[1]; b = aData[2];
|
||||
#endif
|
||||
if (aAlpha != 0xFF) {
|
||||
if (aAlpha == 0) {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
} else {
|
||||
r = Premultiply(r, aAlpha);
|
||||
g = Premultiply(g, aAlpha);
|
||||
b = Premultiply(b, aAlpha);
|
||||
}
|
||||
}
|
||||
return (aAlpha << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 _NSTHEBESIMAGE_H_
|
||||
#define _NSTHEBESIMAGE_H_
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
class nsThebesImage : public nsIImage
|
||||
{
|
||||
public:
|
||||
nsThebesImage();
|
||||
~nsThebesImage();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
|
||||
virtual PRInt32 GetBytesPix();
|
||||
virtual PRBool GetIsRowOrderTopToBottom();
|
||||
virtual PRInt32 GetWidth();
|
||||
virtual PRInt32 GetHeight();
|
||||
virtual PRUint8 *GetBits();
|
||||
virtual PRInt32 GetLineStride();
|
||||
virtual PRBool GetHasAlphaMask();
|
||||
virtual PRUint8 *GetAlphaBits();
|
||||
virtual PRInt32 GetAlphaLineStride();
|
||||
virtual PRBool GetIsImageComplete();
|
||||
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
|
||||
virtual nsresult Optimize(nsIDeviceContext* aContext);
|
||||
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 DrawTile(nsIRenderingContext &aContext,
|
||||
nsIDrawingSurface *aSurface,
|
||||
PRInt32 aSXOffset, PRInt32 aSYOffset,
|
||||
PRInt32 aPadX, PRInt32 aPadY,
|
||||
const nsRect &aTileRect);
|
||||
NS_IMETHOD DrawToImage(nsIImage* aDstImage,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
|
||||
|
||||
virtual PRInt8 GetAlphaDepth();
|
||||
virtual void* GetBitInfo();
|
||||
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
|
||||
|
||||
void UpdateFromLockedData();
|
||||
|
||||
gfxASurface* ThebesSurface() {
|
||||
if (mOptSurface)
|
||||
return mOptSurface;
|
||||
return mImageSurface;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
nsRect mDecoded;
|
||||
|
||||
nsRefPtr<gfxImageSurface> mImageSurface;
|
||||
nsRefPtr<gfxASurface> mOptSurface;
|
||||
|
||||
// temporary buffers for Lock()
|
||||
PRUint8* mLockedData;
|
||||
PRUint8* mLockedAlpha;
|
||||
|
||||
PRUint8 mAlphaDepth;
|
||||
PRUint8 mRealAlphaDepth;
|
||||
PRPackedBool mLocked;
|
||||
PRPackedBool mHadAnyData;
|
||||
PRPackedBool mUpToDate;
|
||||
};
|
||||
|
||||
#endif /* _NSTHEBESIMAGE_H_ */
|
|
@ -0,0 +1,212 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 "nsThebesRegion.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesRegion, nsIRegion)
|
||||
|
||||
nsThebesRegion::nsThebesRegion()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsresult nsThebesRegion::Init (void)
|
||||
{
|
||||
mRegion.SetEmpty();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsThebesRegion::SetTo (const nsIRegion &aRegion)
|
||||
{
|
||||
const nsThebesRegion* pRegion = NS_STATIC_CAST (const nsThebesRegion*, &aRegion);
|
||||
mRegion = pRegion->mRegion;
|
||||
}
|
||||
|
||||
void nsThebesRegion::SetTo (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
mRegion = nsRect (aX, aY, aWidth, aHeight);
|
||||
}
|
||||
|
||||
void nsThebesRegion::Intersect (const nsIRegion &aRegion)
|
||||
{
|
||||
const nsThebesRegion* pRegion = NS_STATIC_CAST (const nsThebesRegion*, &aRegion);
|
||||
mRegion.And (mRegion, pRegion->mRegion);
|
||||
}
|
||||
|
||||
void nsThebesRegion::Intersect (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
mRegion.And (mRegion, nsRect (aX, aY, aWidth, aHeight));
|
||||
}
|
||||
|
||||
void nsThebesRegion::Union (const nsIRegion &aRegion)
|
||||
{
|
||||
const nsThebesRegion* pRegion = NS_STATIC_CAST (const nsThebesRegion*, &aRegion);
|
||||
mRegion.Or (mRegion, pRegion->mRegion);
|
||||
}
|
||||
|
||||
void nsThebesRegion::Union (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
mRegion.Or (mRegion, nsRect (aX, aY, aWidth, aHeight));
|
||||
}
|
||||
|
||||
void nsThebesRegion::Subtract (const nsIRegion &aRegion)
|
||||
{
|
||||
const nsThebesRegion* pRegion = NS_STATIC_CAST (const nsThebesRegion*, &aRegion);
|
||||
mRegion.Sub (mRegion, pRegion->mRegion);
|
||||
}
|
||||
|
||||
void nsThebesRegion::Subtract (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
mRegion.Sub (mRegion, nsRect (aX, aY, aWidth, aHeight));
|
||||
}
|
||||
|
||||
PRBool nsThebesRegion::IsEmpty (void)
|
||||
{
|
||||
return mRegion.IsEmpty ();
|
||||
}
|
||||
|
||||
PRBool nsThebesRegion::IsEqual (const nsIRegion &aRegion)
|
||||
{
|
||||
const nsThebesRegion* pRegion = NS_STATIC_CAST (const nsThebesRegion*, &aRegion);
|
||||
return mRegion.IsEqual (pRegion->mRegion);
|
||||
}
|
||||
|
||||
void nsThebesRegion::GetBoundingBox (PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
|
||||
{
|
||||
nsRect BoundRect;
|
||||
BoundRect = mRegion.GetBounds();
|
||||
*aX = BoundRect.x;
|
||||
*aY = BoundRect.y;
|
||||
*aWidth = BoundRect.width;
|
||||
*aHeight = BoundRect.height;
|
||||
}
|
||||
|
||||
void nsThebesRegion::Offset (PRInt32 aXOffset, PRInt32 aYOffset)
|
||||
{
|
||||
mRegion.MoveBy (aXOffset, aYOffset);
|
||||
}
|
||||
|
||||
PRBool nsThebesRegion::ContainsRect (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
nsRegion TmpRegion;
|
||||
TmpRegion.And (mRegion, nsRect (aX, aY, aWidth, aHeight));
|
||||
return (!TmpRegion.IsEmpty ());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRegion::GetRects (nsRegionRectSet **aRects)
|
||||
{
|
||||
if (!aRects)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsRegionRectSet* pRegionSet = *aRects;
|
||||
PRUint32 NumRects = mRegion.GetNumRects ();
|
||||
|
||||
if (pRegionSet == nsnull) // Not yet allocated
|
||||
{
|
||||
PRUint8* pBuf = new PRUint8 [sizeof (nsRegionRectSet) + NumRects * sizeof (nsRegionRect)];
|
||||
pRegionSet = NS_REINTERPRET_CAST (nsRegionRectSet*, pBuf);
|
||||
pRegionSet->mRectsLen = NumRects + 1;
|
||||
} else // Already allocated in previous call
|
||||
{
|
||||
if (NumRects > pRegionSet->mRectsLen) // passed array is not big enough - reallocate it.
|
||||
{
|
||||
delete [] NS_REINTERPRET_CAST (PRUint8*, pRegionSet);
|
||||
PRUint8* pBuf = new PRUint8 [sizeof (nsRegionRectSet) + NumRects * sizeof (nsRegionRect)];
|
||||
pRegionSet = NS_REINTERPRET_CAST (nsRegionRectSet*, pBuf);
|
||||
pRegionSet->mRectsLen = NumRects + 1;
|
||||
}
|
||||
}
|
||||
pRegionSet->mNumRects = NumRects;
|
||||
*aRects = pRegionSet;
|
||||
|
||||
|
||||
nsRegionRectIterator ri (mRegion);
|
||||
nsRegionRect* pDest = &pRegionSet->mRects [0];
|
||||
const nsRect* pSrc;
|
||||
|
||||
while ((pSrc = ri.Next ()))
|
||||
{
|
||||
pDest->x = pSrc->x;
|
||||
pDest->y = pSrc->y;
|
||||
pDest->width = pSrc->width;
|
||||
pDest->height = pSrc->height;
|
||||
|
||||
pDest++;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRegion::FreeRects (nsRegionRectSet *aRects)
|
||||
{
|
||||
if (!aRects)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
delete [] NS_REINTERPRET_CAST (PRUint8*, aRects);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRegion::GetNativeRegion (void *&aRegion) const
|
||||
{
|
||||
aRegion = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRegion::GetRegionComplexity (nsRegionComplexity &aComplexity) const
|
||||
{
|
||||
switch (mRegion.GetNumRects ())
|
||||
{
|
||||
case 0: aComplexity = eRegionComplexity_empty; break;
|
||||
case 1: aComplexity = eRegionComplexity_rect; break;
|
||||
default: aComplexity = eRegionComplexity_complex; break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesRegion::GetNumRects (PRUint32 *aRects) const
|
||||
{
|
||||
*aRects = mRegion.GetNumRects ();
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 NSTHEBESREGION__H__
|
||||
#define NSTHEBESREGION__H__
|
||||
|
||||
#include "nsIRegion.h"
|
||||
#include "nsRegion.h"
|
||||
|
||||
class nsThebesRegion : public nsIRegion
|
||||
{
|
||||
public:
|
||||
nsThebesRegion();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIRegion
|
||||
nsresult Init (void);
|
||||
void SetTo (const nsIRegion &aRegion);
|
||||
void SetTo (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
void Intersect (const nsIRegion &aRegion);
|
||||
void Intersect (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
void Union (const nsIRegion &aRegion);
|
||||
void Union (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
void Subtract (const nsIRegion &aRegion);
|
||||
void Subtract (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
PRBool IsEmpty (void);
|
||||
PRBool IsEqual (const nsIRegion &aRegion);
|
||||
void GetBoundingBox (PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight);
|
||||
void Offset (PRInt32 aXOffset, PRInt32 aYOffset);
|
||||
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;
|
||||
|
||||
protected:
|
||||
nsRegion mRegion;
|
||||
};
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,270 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 NSTHEBESRENDERINGCONTEXT__H__
|
||||
#define NSTHEBESRENDERINGCONTEXT__H__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIThebesFontMetrics.h"
|
||||
#include "nsIThebesRenderingContext.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
class nsIImage;
|
||||
|
||||
class nsThebesDrawingSurface;
|
||||
|
||||
class nsThebesRenderingContext : public nsIRenderingContext, public nsIThebesRenderingContext
|
||||
{
|
||||
public:
|
||||
nsThebesRenderingContext();
|
||||
virtual ~nsThebesRenderingContext();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWidget);
|
||||
NS_IMETHOD Init(nsIDeviceContext* aContext, nsIDrawingSurface *aSurface);
|
||||
NS_IMETHOD CommonInit(void);
|
||||
NS_IMETHOD Reset(void);
|
||||
NS_IMETHOD GetDeviceContext(nsIDeviceContext *& aDeviceContext);
|
||||
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);
|
||||
NS_IMETHOD DrawNativeWidgetPixmap(void* aSrcSurfaceBlack,
|
||||
void* aSrcSurfaceWhite,
|
||||
const nsIntSize& aSrcSize,
|
||||
const nsPoint& aDestPos);
|
||||
NS_IMETHOD PushState(void);
|
||||
NS_IMETHOD PopState(void);
|
||||
NS_IMETHOD IsVisibleRect(const nsRect& aRect, PRBool &aIsVisible);
|
||||
NS_IMETHOD SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
|
||||
NS_IMETHOD GetClipRect(nsRect &aRect, PRBool &aHasLocalClip);
|
||||
NS_IMETHOD SetLineStyle(nsLineStyle aLineStyle);
|
||||
NS_IMETHOD GetLineStyle(nsLineStyle &aLineStyle);
|
||||
NS_IMETHOD GetPenMode(nsPenMode &aPenMode);
|
||||
NS_IMETHOD SetPenMode(nsPenMode aPenMode);
|
||||
NS_IMETHOD SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
|
||||
NS_IMETHOD CopyClipRegion(nsIRegion &aRegion);
|
||||
NS_IMETHOD GetClipRegion(nsIRegion **aRegion);
|
||||
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 CreateDrawingSurface(nsNativeWidget aWidget, 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 FlushRect(const nsRect& aRect);
|
||||
NS_IMETHOD FlushRect(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(char aC, nscoord &aWidth);
|
||||
NS_IMETHOD GetWidth(PRUnichar aC, nscoord &aWidth,
|
||||
PRInt32 *aFontID = nsnull);
|
||||
NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth,
|
||||
PRInt32 *aFontID = nsnull);
|
||||
NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth);
|
||||
NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength,
|
||||
nscoord& aWidth);
|
||||
NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord &aWidth, PRInt32 *aFontID = nsnull);
|
||||
NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength,
|
||||
nsTextDimensions& aDimensions);
|
||||
NS_IMETHOD GetTextDimensions(const PRUnichar* aString, PRUint32 aLength,
|
||||
nsTextDimensions& aDimensions, PRInt32* aFontID = nsnull);
|
||||
|
||||
NS_IMETHOD PushFilter(const nsRect& aRect, PRBool aAreaIsOpaque, float aOpacity);
|
||||
NS_IMETHOD PopFilter();
|
||||
|
||||
#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS)
|
||||
NS_IMETHOD GetTextDimensions(const char* aString,
|
||||
PRInt32 aLength,
|
||||
PRInt32 aAvailWidth,
|
||||
PRInt32* aBreaks,
|
||||
PRInt32 aNumBreaks,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32& aNumCharsFit,
|
||||
nsTextDimensions& aLastWordDimensions,
|
||||
PRInt32* aFontID = nsnull);
|
||||
|
||||
NS_IMETHOD GetTextDimensions(const PRUnichar* aString,
|
||||
PRInt32 aLength,
|
||||
PRInt32 aAvailWidth,
|
||||
PRInt32* aBreaks,
|
||||
PRInt32 aNumBreaks,
|
||||
nsTextDimensions& aDimensions,
|
||||
PRInt32& aNumCharsFit,
|
||||
nsTextDimensions& aLastWordDimensions,
|
||||
PRInt32* aFontID = nsnull);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD DrawString(const char *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
const nscoord* aSpacing = nsnull);
|
||||
NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
PRInt32 aFontID = -1,
|
||||
const nscoord* aSpacing = nsnull);
|
||||
NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY,
|
||||
PRInt32 aFontID = -1,
|
||||
const nscoord* aSpacing = nsnull);
|
||||
NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface *aSrcSurf,
|
||||
PRInt32 aSrcX, PRInt32 aSrcY,
|
||||
const nsRect &aDestBounds,
|
||||
PRUint32 aCopyFlags);
|
||||
virtual void* GetNativeGraphicData(GraphicDataType aType);
|
||||
NS_IMETHOD GetBackbuffer(const nsRect &aRequestedSize,
|
||||
const nsRect &aMaxSize,
|
||||
PRBool aForBlending,
|
||||
nsIDrawingSurface* &aBackbuffer);
|
||||
NS_IMETHOD ReleaseBackbuffer(void);
|
||||
NS_IMETHOD DestroyCachedBackbuffer(void);
|
||||
NS_IMETHOD UseBackbuffer(PRBool* aUseBackbuffer);
|
||||
|
||||
NS_IMETHOD PushTranslation(PushedTranslation* aState);
|
||||
NS_IMETHOD PopTranslation(PushedTranslation* aState);
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
NS_IMETHOD GetBoundingMetrics(const char* aString, PRUint32 aLength, nsBoundingMetrics& aBoundingMetrics);
|
||||
NS_IMETHOD GetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength,
|
||||
nsBoundingMetrics& aBoundingMetrics,
|
||||
PRInt32* aFontID);
|
||||
|
||||
#endif // MOZ_MATHML
|
||||
|
||||
|
||||
NS_IMETHOD DrawImage(imgIContainer *aImage,
|
||||
const nsRect &aSrcRect,
|
||||
const nsRect &aDestRect);
|
||||
NS_IMETHOD DrawTile(imgIContainer *aImage, nscoord aXOffset, nscoord aYOffset,
|
||||
const nsRect * aTargetRect);
|
||||
NS_IMETHOD SetRightToLeftText(PRBool aIsRTL) { return NS_OK; }
|
||||
|
||||
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 RenderEPS(const nsRect& aRect, FILE *aDataFile);
|
||||
|
||||
// Thebes specific stuff
|
||||
|
||||
gfxContext *Thebes() { return mThebes; }
|
||||
|
||||
nsTransform2D& CurrentTransform();
|
||||
|
||||
void TransformCoord (nscoord *aX, nscoord *aY);
|
||||
|
||||
nsresult AllocateBackbuffer(const nsRect &aRequestedSize, const nsRect &aMaxSize, nsIDrawingSurface* &aBackbuffer, PRBool aCacheBackbuffer, PRUint32 aSurfFlags);
|
||||
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDeviceContext> mDeviceContext;
|
||||
// cached pixels2twips, twips2pixels values
|
||||
double mP2T, mT2P;
|
||||
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
|
||||
// we need to manage our own clip region (since we can't get at
|
||||
// the old one from cairo)
|
||||
nsCOMPtr<nsIThebesFontMetrics> mFontMetrics;
|
||||
|
||||
nsLineStyle mLineStyle;
|
||||
nscolor mColor;
|
||||
|
||||
nsRefPtr<gfxContext> mThebes;
|
||||
nsCOMPtr<nsThebesDrawingSurface> mDrawingSurface;
|
||||
|
||||
// for handing out to people
|
||||
void UpdateTempTransformMatrix();
|
||||
nsTransform2D mTempTransform;
|
||||
};
|
||||
|
||||
#endif // NSCAIRORENDERINGCONTEXT__H__
|
|
@ -30,4 +30,8 @@ ifeq ($(MOZ_GFX_TOOLKIT),gtk2)
|
|||
EXPORTS += gfxXlibSurface.h
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_GLITZ
|
||||
EXPORTS += gfxGlitzSurface.h
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -42,10 +42,25 @@
|
|||
|
||||
#include "gfxTypes.h"
|
||||
|
||||
/**
|
||||
* A surface is something you can draw on. Instantiate a subclass of this
|
||||
* abstract class, and use gfxContext to draw on this surface.
|
||||
*/
|
||||
class gfxASurface {
|
||||
THEBES_DECL_REFCOUNTING_ABSTRACT
|
||||
|
||||
public:
|
||||
/**
|
||||
* The format for an image surface. For all formats with alpha data, 0
|
||||
* means transparent, 1 or 255 means fully opaque.
|
||||
*/
|
||||
typedef enum {
|
||||
ImageFormatARGB32, ///< ARGB data in native endianness, using premultiplied alpha
|
||||
ImageFormatRGB24, ///< xRGB data in native endianness
|
||||
ImageFormatA8, ///< Only an alpha channel
|
||||
ImageFormatA1 ///< Packed transparency information (one byte refers to 8 pixels)
|
||||
} gfxImageFormat;
|
||||
|
||||
/*** this DOES NOT addref the surface */
|
||||
cairo_surface_t* CairoSurface() { return mSurface; }
|
||||
|
||||
|
|
|
@ -42,18 +42,39 @@
|
|||
|
||||
#include "gfxTypes.h"
|
||||
|
||||
/**
|
||||
* A color value, storing red, green, blue and alpha components.
|
||||
* This class does not use premultiplied alpha.
|
||||
*
|
||||
* XXX should this use doubles (instead of gfxFloat), for consistency with
|
||||
* cairo?
|
||||
*/
|
||||
struct gfxRGBA {
|
||||
gfxFloat r, g, b, a;
|
||||
|
||||
gfxRGBA() { }
|
||||
gfxRGBA(const gfxRGBA& c) : r(c.r), g(c.g), b(c.b), a(c.a) {}
|
||||
/**
|
||||
* Intialize this color using explicit red, green, blue and alpha
|
||||
* values.
|
||||
*/
|
||||
gfxRGBA(gfxFloat _r, gfxFloat _g, gfxFloat _b, gfxFloat _a=1.0) : r(_r), g(_g), b(_b), a(_a) {}
|
||||
/**
|
||||
* Initialize this color from a packed 32-bit color.
|
||||
* Premultiplied alpha isn't used.
|
||||
* This uses ABGR byte order in the native endianness.
|
||||
*
|
||||
* @see gfxRGBA::Packed
|
||||
*/
|
||||
gfxRGBA(PRUint32 c) {
|
||||
r = ((c >> 0) & 0xff) / 255.0;
|
||||
g = ((c >> 8) & 0xff) / 255.0;
|
||||
b = ((c >> 16) & 0xff) / 255.0;
|
||||
a = ((c >> 24) & 0xff) / 255.0;
|
||||
}
|
||||
/**
|
||||
* Initialize this color by parsing the given string.
|
||||
*/
|
||||
gfxRGBA(const char* str) {
|
||||
a = 1.0;
|
||||
// if aString[0] is a #, parse it as hex
|
||||
|
@ -61,6 +82,11 @@ struct gfxRGBA {
|
|||
// if aString[0] is a number, parse it loosely as hex
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this color value as a packed 32-bit integer. This uses ABGR
|
||||
* byte order in the native endianness, as accepted by the corresponding
|
||||
* constructor of this class.
|
||||
*/
|
||||
PRUint32 Packed() const {
|
||||
return (((PRUint8)(a * 255.0) << 24) |
|
||||
((PRUint8)(b * 255.0) << 16) |
|
||||
|
@ -68,6 +94,10 @@ struct gfxRGBA {
|
|||
((PRUint8)(r * 255.0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this color to a hex value. For example, for rgb(255,0,0),
|
||||
* this will return FF0000.
|
||||
*/
|
||||
// XXX I'd really prefer to just have this return an nsACString
|
||||
// Does this function even make sense, since we're just ignoring the alpha value?
|
||||
void Hex(nsACString& result) const {
|
||||
|
|
|
@ -53,10 +53,24 @@ class gfxRegion;
|
|||
class gfxFilter;
|
||||
class gfxTextRun;
|
||||
|
||||
/**
|
||||
* This is the main class for doing actual drawing. It is initialized using
|
||||
* a surface and can be drawn on. It manages various state information like
|
||||
* a current transformation matrix (CTM), a current path, current color,
|
||||
* etc.
|
||||
*
|
||||
* All drawing happens by creating a path and then stroking or filling it.
|
||||
* The functions like Rectangle and Arc do not do any drawing themselves.
|
||||
* When a path is drawn (stroked or filled), it is filled/stroked with a
|
||||
* pattern set by SetPattern, SetColor or SetSource.
|
||||
*/
|
||||
class gfxContext {
|
||||
THEBES_DECL_REFCOUNTING
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initialize this context from a surface.
|
||||
*/
|
||||
gfxContext(gfxASurface *surface);
|
||||
~gfxContext();
|
||||
|
||||
|
@ -75,27 +89,81 @@ public:
|
|||
** Paths & Drawing
|
||||
**/
|
||||
|
||||
// these do not consume the current path
|
||||
/**
|
||||
* Stroke the current path using the current settings (such as line
|
||||
* width and color).
|
||||
* A path is set up using functions such as Line, Rectangle and Arc.
|
||||
*
|
||||
* Does not consume the current path.
|
||||
*/
|
||||
void Stroke();
|
||||
/**
|
||||
* Fill the current path according to the current settings.
|
||||
*
|
||||
* Does not consume the current path.
|
||||
*/
|
||||
void Fill();
|
||||
|
||||
/**
|
||||
* Forgets the current path.
|
||||
*/
|
||||
void NewPath();
|
||||
|
||||
/**
|
||||
* Closes the path, i.e. connects the last drawn point to the first one.
|
||||
*
|
||||
* Filling a path will implicitly close it.
|
||||
*/
|
||||
void ClosePath();
|
||||
|
||||
/**
|
||||
* Moves the pen to a new point without drawing a line.
|
||||
*/
|
||||
void MoveTo(gfxPoint pt);
|
||||
|
||||
/**
|
||||
* Draws a line from the current point to pt.
|
||||
*
|
||||
* @see MoveTo
|
||||
*/
|
||||
void LineTo(gfxPoint pt);
|
||||
|
||||
/**
|
||||
* Draws a quadratic Bézier curve with control points pt1, pt2 and pt3.
|
||||
*/
|
||||
void CurveTo(gfxPoint pt1, gfxPoint pt2, gfxPoint pt3);
|
||||
|
||||
// clockwise arc
|
||||
/**
|
||||
* Draws a clockwise arc (i.e. a circle segment).
|
||||
* @param center The center of the circle
|
||||
* @param radius The radius of the circle
|
||||
* @param angle1 Starting angle for the segment
|
||||
* @param angle2 Ending angle
|
||||
*/
|
||||
void Arc(gfxPoint center, gfxFloat radius,
|
||||
gfxFloat angle1, gfxFloat angle2);
|
||||
|
||||
// counterclockwise arc
|
||||
/**
|
||||
* Draws a counter-clockwise arc (i.e. a circle segment).
|
||||
* @param center The center of the circle
|
||||
* @param radius The radius of the circle
|
||||
* @param angle1 Starting angle for the segment
|
||||
* @param angle2 Ending angle
|
||||
*/
|
||||
|
||||
void NegativeArc(gfxPoint center, gfxFloat radius,
|
||||
gfxFloat angle1, gfxFloat angle2);
|
||||
|
||||
// path helpers
|
||||
/**
|
||||
* Draws a line from start to end.
|
||||
*/
|
||||
void Line(gfxPoint start, gfxPoint end); // XXX snapToPixels option?
|
||||
|
||||
/**
|
||||
* Draws the rectangle given by rect.
|
||||
* @param snapToPixels ?
|
||||
*/
|
||||
void Rectangle(gfxRect rect, PRBool snapToPixels = PR_FALSE);
|
||||
void Ellipse(gfxPoint center, gfxSize dimensions);
|
||||
void Polygon(const gfxPoint *points, PRUint32 numPoints);
|
||||
|
@ -104,56 +172,172 @@ public:
|
|||
** Text
|
||||
**/
|
||||
|
||||
// Add the text outline to the current path
|
||||
/**
|
||||
* Add the text outline to the current path.
|
||||
*/
|
||||
void AddStringToPath(gfxTextRun& text, int pos, int len);
|
||||
|
||||
// Draw a substring of the text run at the current point
|
||||
/**
|
||||
* Draw a substring of the text run at the current point.
|
||||
*/
|
||||
void DrawString(gfxTextRun& text, int pos, int len);
|
||||
|
||||
/**
|
||||
** Transformation Matrix manipulation
|
||||
**/
|
||||
|
||||
/**
|
||||
* Adds a translation to the current matrix. This translation takes place
|
||||
* before the previously set transformations.
|
||||
*/
|
||||
void Translate(gfxPoint pt);
|
||||
void Scale(gfxFloat x, gfxFloat y);
|
||||
void Rotate(gfxFloat angle); // radians
|
||||
|
||||
// post-multiplies 'other' onto the current CTM
|
||||
/**
|
||||
* Adds a scale to the current matrix. This scaling takes place before the
|
||||
* previously set transformations.
|
||||
*/
|
||||
void Scale(gfxFloat x, gfxFloat y);
|
||||
|
||||
/**
|
||||
* Adds a rotation around the origin to the current matrix. This rotation
|
||||
* takes place before the previously set transformations.
|
||||
*
|
||||
* @param angle The angle in radians.
|
||||
*/
|
||||
void Rotate(gfxFloat angle);
|
||||
|
||||
/**
|
||||
* Post-multiplies 'other' onto the current CTM, i.e. this
|
||||
* matrix's transformation will take place before the previously set
|
||||
* transformations.
|
||||
*/
|
||||
void Multiply(const gfxMatrix& other);
|
||||
|
||||
/**
|
||||
* Replaces the current transformation matrix with matrix.
|
||||
*/
|
||||
void SetMatrix(const gfxMatrix& matrix);
|
||||
|
||||
/**
|
||||
* Sets the transformation matrix to the identity matrix.
|
||||
*/
|
||||
void IdentityMatrix();
|
||||
|
||||
/**
|
||||
* Returns the current transformation matrix.
|
||||
*/
|
||||
gfxMatrix CurrentMatrix() const;
|
||||
|
||||
/**
|
||||
* Converts a point from device to user coordinates using the inverse
|
||||
* transformation matrix.
|
||||
*/
|
||||
gfxPoint DeviceToUser(gfxPoint point) const;
|
||||
|
||||
/**
|
||||
* Converts a size from device to user coordinates. This does not apply
|
||||
* translation components of the matrix.
|
||||
*/
|
||||
gfxSize DeviceToUser(gfxSize size) const;
|
||||
|
||||
/**
|
||||
* Converts a rectangle from device to user coordinates; this has the
|
||||
* same effect as using DeviceToUser on both the rectangle's point and
|
||||
* size.
|
||||
*/
|
||||
gfxRect DeviceToUser(gfxRect rect) const;
|
||||
|
||||
/**
|
||||
* Converts a point from user to device coordinates using the inverse
|
||||
* transformation matrix.
|
||||
*/
|
||||
gfxPoint UserToDevice(gfxPoint point) const;
|
||||
|
||||
/**
|
||||
* Converts a size from user to device coordinates. This does not apply
|
||||
* translation components of the matrix.
|
||||
*/
|
||||
gfxSize UserToDevice(gfxSize size) const;
|
||||
|
||||
/**
|
||||
* Converts a rectangle from user to device coordinates; this has the
|
||||
* same effect as using DeviceToUser on both the rectangle's point and
|
||||
* size.
|
||||
*/
|
||||
gfxRect UserToDevice(gfxRect rect) const;
|
||||
|
||||
/**
|
||||
* Takes the given rect and tries to align it to device pixels. If
|
||||
* this succeeds, the method will return PR_TRUE, and the rect will
|
||||
* be in device coordinates (already transformed by the CTM). If it
|
||||
* fails, the method will return PR_FALSE, and the rect will not be
|
||||
* changed.
|
||||
*/
|
||||
PRBool UserToDevicePixelSnapped(gfxRect& rect) const;
|
||||
|
||||
/**
|
||||
* Attempts to pixel snap the rectangle, add it to the current
|
||||
* path, and to set pattern as the current painting source. This
|
||||
* should be used for drawing filled pixel-snapped rectangles (like
|
||||
* images), because the CTM at the time of the SetPattern call needs
|
||||
* to have a snapped translation, or you get smeared images.
|
||||
*/
|
||||
void PixelSnappedRectangleAndSetPattern(const gfxRect& rect, gfxPattern *pattern);
|
||||
|
||||
/**
|
||||
** Painting sources
|
||||
**/
|
||||
|
||||
/**
|
||||
* Uses a solid color for drawing.
|
||||
*/
|
||||
void SetColor(const gfxRGBA& c);
|
||||
|
||||
/**
|
||||
* Uses a pattern for drawing.
|
||||
*/
|
||||
void SetPattern(gfxPattern *pattern);
|
||||
void SetSource(gfxASurface *surface) {
|
||||
SetSource(surface, gfxPoint(0, 0));
|
||||
}
|
||||
void SetSource(gfxASurface* surface, gfxPoint offset);
|
||||
|
||||
/**
|
||||
* Uses a surface for drawing. This is a shorthand for creating a
|
||||
* pattern and setting it.
|
||||
*
|
||||
* @param offset ?
|
||||
*/
|
||||
void SetSource(gfxASurface* surface, gfxPoint offset = gfxPoint(0.0, 0.0));
|
||||
|
||||
/**
|
||||
** Painting
|
||||
**/
|
||||
/**
|
||||
* Paints the current source surface/pattern everywhere in the current
|
||||
* clip region.
|
||||
*/
|
||||
void Paint(gfxFloat alpha = 1.0);
|
||||
|
||||
/**
|
||||
** Painting with a Mask
|
||||
**/
|
||||
/**
|
||||
* Like Paint, except that it only draws the source where pattern is
|
||||
* non-transparent.
|
||||
*/
|
||||
void Mask(gfxPattern *pattern);
|
||||
|
||||
/**
|
||||
* Shorthand for creating a pattern and calling the pattern-taking
|
||||
* variant of Mask.
|
||||
*/
|
||||
void Mask(gfxASurface *surface, gfxPoint offset = gfxPoint(0.0, 0.0));
|
||||
|
||||
/**
|
||||
** Shortcuts
|
||||
**/
|
||||
|
||||
// Creates a new path with a rectangle from 0,0 to size.w,size.h
|
||||
// and calls cairo_fill
|
||||
/**
|
||||
* Creates a new path with a rectangle from 0,0 to size.w,size.h
|
||||
* and calls cairo_fill.
|
||||
*/
|
||||
void DrawSurface(gfxASurface *surface, gfxSize size);
|
||||
|
||||
/**
|
||||
|
@ -170,7 +354,16 @@ public:
|
|||
void SetDash(gfxFloat *dashes, int ndash, gfxFloat offset);
|
||||
//void getDash() const;
|
||||
|
||||
/**
|
||||
* Sets the line width that's used for line drawing.
|
||||
*/
|
||||
void SetLineWidth(gfxFloat width);
|
||||
|
||||
/**
|
||||
* Returns the currently set line width.
|
||||
*
|
||||
* @see SetLineWidth
|
||||
*/
|
||||
gfxFloat CurrentLineWidth() const;
|
||||
|
||||
enum GraphicsLineCap {
|
||||
|
@ -178,6 +371,9 @@ public:
|
|||
LINE_CAP_ROUND,
|
||||
LINE_CAP_SQUARE
|
||||
};
|
||||
/**
|
||||
* Sets the line caps, i.e. how line endings are drawn.
|
||||
*/
|
||||
void SetLineCap(GraphicsLineCap cap);
|
||||
GraphicsLineCap CurrentLineCap() const;
|
||||
|
||||
|
@ -186,6 +382,10 @@ public:
|
|||
LINE_JOIN_ROUND,
|
||||
LINE_JOIN_BEVEL
|
||||
};
|
||||
/**
|
||||
* Sets the line join, i.e. how the connection between two lines is
|
||||
* drawn.
|
||||
*/
|
||||
void SetLineJoin(GraphicsLineJoin join);
|
||||
GraphicsLineJoin CurrentLineJoin() const;
|
||||
|
||||
|
@ -198,21 +398,30 @@ public:
|
|||
|
||||
// define enum for operators (clear, src, dst, etc)
|
||||
enum GraphicsOperator {
|
||||
OPERATOR_CLEAR,
|
||||
OPERATOR_SRC,
|
||||
OPERATOR_DST,
|
||||
OPERATOR_OVER,
|
||||
OPERATOR_OVER_REVERSE,
|
||||
OPERATOR_IN,
|
||||
OPERATOR_IN_REVERSE,
|
||||
OPERATOR_OUT,
|
||||
OPERATOR_OUT_REVERSE,
|
||||
OPERATOR_ATOP,
|
||||
OPERATOR_ATOP_REVERSE,
|
||||
OPERATOR_XOR,
|
||||
OPERATOR_ADD,
|
||||
OPERATOR_SATURATE
|
||||
OPERATOR_CLEAR = CAIRO_OPERATOR_CLEAR,
|
||||
OPERATOR_SOURCE = CAIRO_OPERATOR_SOURCE,
|
||||
|
||||
OPERATOR_OVER = CAIRO_OPERATOR_OVER,
|
||||
OPERATOR_IN = CAIRO_OPERATOR_IN,
|
||||
OPERATOR_OUT = CAIRO_OPERATOR_OUT,
|
||||
OPERATOR_ATOP = CAIRO_OPERATOR_ATOP,
|
||||
|
||||
OPERATOR_DEST = CAIRO_OPERATOR_DEST,
|
||||
OPERATOR_DEST_OVER = CAIRO_OPERATOR_DEST_OVER,
|
||||
OPERATOR_DEST_IN = CAIRO_OPERATOR_DEST_IN,
|
||||
OPERATOR_DEST_OUT = CAIRO_OPERATOR_DEST_OUT,
|
||||
OPERATOR_DEST_ATOP = CAIRO_OPERATOR_DEST_ATOP,
|
||||
|
||||
OPERATOR_XOR = CAIRO_OPERATOR_XOR,
|
||||
OPERATOR_ADD = CAIRO_OPERATOR_ADD,
|
||||
OPERATOR_SATURATE = CAIRO_OPERATOR_SATURATE
|
||||
};
|
||||
/**
|
||||
* Sets the operator used for all further drawing. The operator affects
|
||||
* how drawing something will modify the destination. For example, the
|
||||
* OVER operator will do alpha blending of source and destination, while
|
||||
* SOURCE will replace the destination with the source.
|
||||
*/
|
||||
void SetOperator(GraphicsOperator op);
|
||||
GraphicsOperator CurrentOperator() const;
|
||||
|
||||
|
@ -232,11 +441,22 @@ public:
|
|||
** Clipping
|
||||
**/
|
||||
|
||||
void Clip(); // will clip the last path you've drawn
|
||||
void ResetClip(); // will remove any clip set
|
||||
// Helper functions that will create a rect path and call Clip().
|
||||
// Any current path will be destroyed by these functions!
|
||||
//
|
||||
/**
|
||||
* Clips all further drawing to the current path.
|
||||
* This does not consume the current path.
|
||||
*/
|
||||
void Clip();
|
||||
|
||||
/**
|
||||
* Undoes any clipping. Further drawings will only be restricted by the
|
||||
* surface dimensions.
|
||||
*/
|
||||
void ResetClip();
|
||||
|
||||
/**
|
||||
* Helper functions that will create a rect path and call Clip().
|
||||
* Any current path will be destroyed by these functions!
|
||||
*/
|
||||
void Clip(gfxRect rect); // will clip to a rect
|
||||
void Clip(const gfxRegion& region); // will clip to a region
|
||||
|
||||
|
@ -249,11 +469,15 @@ public:
|
|||
FILTER_OPAQUE_DRAW
|
||||
};
|
||||
|
||||
// Start rendering under the filter. We guarantee not to draw outside 'maxArea'.
|
||||
/**
|
||||
* Start rendering under the filter. We guarantee not to draw outside 'maxArea'.
|
||||
*/
|
||||
void PushFilter(gfxFilter& filter, FilterHints hints, gfxRect& maxArea);
|
||||
|
||||
// Completed rendering under the filter, composite what we rendered back to the
|
||||
// underlying surface using the filter.
|
||||
/**
|
||||
* Completed rendering under the filter, composite what we rendered back to the
|
||||
* underlying surface using the filter.
|
||||
*/
|
||||
void PopFilter();
|
||||
|
||||
private:
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
|
||||
#include "gfxTypes.h"
|
||||
|
||||
/**
|
||||
* A filter.
|
||||
*
|
||||
* @see gfxContext::PushFilter, gfxContext::PopFilter
|
||||
*/
|
||||
class gfxFilter {
|
||||
static gfxFilter* CreateOpacityFilter(gfxFloat alpha);
|
||||
// CreateGaussianFilter, etc
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 Oracle Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Oracle Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 GFX_GLITZSURFACE_H
|
||||
#define GFX_GLITZSURFACE_H
|
||||
|
||||
#include "gfxASurface.h"
|
||||
|
||||
#include <cairo-glitz.h>
|
||||
|
||||
/**
|
||||
* A surface that wraps a glitz surface.
|
||||
*/
|
||||
class gfxGlitzSurface : public gfxASurface {
|
||||
THEBES_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
public:
|
||||
gfxGlitzSurface(glitz_drawable_t *drawable,
|
||||
glitz_surface_t *glitzSurface,
|
||||
PRBool takeOwnership = PR_FALSE);
|
||||
|
||||
virtual ~gfxGlitzSurface();
|
||||
|
||||
/**
|
||||
* When double-buffering is used, swaps the back and the front buffer.
|
||||
*/
|
||||
void SwapBuffers();
|
||||
|
||||
unsigned long Width();
|
||||
unsigned long Height();
|
||||
|
||||
glitz_surface_t* GlitzSurface() { return mGlitzSurface; }
|
||||
glitz_drawable_t* GlitzDrawable() { return mGlitzDrawable; }
|
||||
|
||||
protected:
|
||||
glitz_drawable_t *mGlitzDrawable;
|
||||
glitz_surface_t *mGlitzSurface;
|
||||
PRBool mOwnsSurface;
|
||||
};
|
||||
|
||||
#endif /* GFX_GLITZSURFACE_H */
|
|
@ -43,17 +43,25 @@
|
|||
|
||||
// ARGB -- raw buffer.. wont be changed.. good for storing data.
|
||||
|
||||
/**
|
||||
* A raw image buffer. The format can be set in the constructor. Its main
|
||||
* purpose is for storing read-only images and using it as a source surface,
|
||||
* but it can also be drawn to.
|
||||
*/
|
||||
class gfxImageSurface : public gfxASurface {
|
||||
THEBES_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
public:
|
||||
typedef enum {
|
||||
ImageFormatARGB32,
|
||||
ImageFormatRGB24,
|
||||
ImageFormatA8,
|
||||
ImageFormatA1
|
||||
} gfxImageFormat;
|
||||
|
||||
/**
|
||||
* Construct an image surface.
|
||||
* @param format Format of the data
|
||||
* @param width Width of the surface in pixels
|
||||
* @param height Height in pixels
|
||||
*
|
||||
* @see gfxImageFormat
|
||||
*
|
||||
* XXX why not unsigned long for the dimensions? And, why not gfxSize?
|
||||
*/
|
||||
gfxImageSurface(gfxImageFormat format, long width, long height);
|
||||
virtual ~gfxImageSurface();
|
||||
|
||||
|
@ -61,7 +69,15 @@ public:
|
|||
int Format() const { return mFormat; }
|
||||
long Width() const { return mWidth; }
|
||||
long Height() const { return mHeight; }
|
||||
/**
|
||||
* Distance in bytes between the start of a line and the start of the
|
||||
* next line.
|
||||
*/
|
||||
long Stride() const;
|
||||
/**
|
||||
* Returns a pointer for the image data. Users of this function can
|
||||
* write to it, but must not attempt to free the buffer.
|
||||
*/
|
||||
unsigned char* Data() { return mData; } // delete this data under us and die.
|
||||
|
||||
private:
|
||||
|
|
|
@ -42,20 +42,44 @@
|
|||
|
||||
#include "gfxPoint.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxRect.h"
|
||||
|
||||
// XX - I don't think this class should use gfxFloat at all,
|
||||
// but should use 'double' and be called gfxDoubleMatrix;
|
||||
// we can then typedef that to gfxMatrix where we typedef
|
||||
// double to be gfxFloat.
|
||||
|
||||
/**
|
||||
* A matrix that represents an affine transformation. Projective
|
||||
* transformations are not supported. This matrix looks like:
|
||||
*
|
||||
* / a b tx \
|
||||
* | c d ty |
|
||||
* \ 0 0 1 /
|
||||
*
|
||||
* So, transforming a point (x, y) results in:
|
||||
*
|
||||
* / a b 0 \ / a * x + c * y + tx \ T
|
||||
* (x y 1) * | c d 0 | = | b * x + d * y + ty |
|
||||
* \ tx ty 1 / \ 1 /
|
||||
*
|
||||
*/
|
||||
class gfxMatrix {
|
||||
protected:
|
||||
cairo_matrix_t mat;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes this matrix as the identity matrix.
|
||||
*/
|
||||
gfxMatrix() { Reset(); }
|
||||
gfxMatrix(const gfxMatrix& m) : mat(m.mat) {}
|
||||
/**
|
||||
* Initializes the matrix from individual components. See the class
|
||||
* description for the layout of the matrix.
|
||||
*/
|
||||
gfxMatrix(gfxFloat a, gfxFloat b, gfxFloat c, gfxFloat d, gfxFloat tx, gfxFloat ty) {
|
||||
// XXX cairo_matrix_init?
|
||||
mat.xx = a; mat.yx = b; mat.xy = c; mat.yy = d; mat.x0 = tx; mat.y0 = ty;
|
||||
}
|
||||
|
||||
|
@ -68,11 +92,17 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-multiplies m onto the matrix.
|
||||
*/
|
||||
const gfxMatrix& operator *= (const gfxMatrix& m) {
|
||||
return Multiply(m);
|
||||
}
|
||||
|
||||
gfxMatrix operator * (const gfxMatrix& m) {
|
||||
/**
|
||||
* Multiplies *this with m and returns the result.
|
||||
*/
|
||||
gfxMatrix operator * (const gfxMatrix& m) const {
|
||||
return gfxMatrix(*this).Multiply(m);
|
||||
}
|
||||
|
||||
|
@ -94,27 +124,52 @@ public:
|
|||
}
|
||||
|
||||
// matrix operations
|
||||
/**
|
||||
* Resets this matrix to the identity matrix.
|
||||
*/
|
||||
const gfxMatrix& Reset() {
|
||||
cairo_matrix_init_identity(&mat);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts this matrix, if possible. Otherwise, the matrix is left
|
||||
* unchanged.
|
||||
*
|
||||
* XXX should this do something with the return value of
|
||||
* cairo_matrix_invert?
|
||||
*/
|
||||
const gfxMatrix& Invert() {
|
||||
cairo_matrix_invert(&mat);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales this matrix. The scale is pre-multiplied onto this matrix,
|
||||
* i.e. the scaling takes place before the other transformations.
|
||||
*/
|
||||
const gfxMatrix& Scale(gfxFloat x, gfxFloat y) {
|
||||
cairo_matrix_scale(&mat, x, y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates this matrix. The translation is pre-multiplied onto this matrix,
|
||||
* i.e. the translation takes place before the other transformations.
|
||||
*/
|
||||
const gfxMatrix& Translate(const gfxPoint& pt) {
|
||||
cairo_matrix_translate(&mat, pt.x, pt.y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates this matrix. The rotation is pre-multiplied onto this matrix,
|
||||
* i.e. the translation takes place after the other transformations.
|
||||
*
|
||||
* @param radians Angle in radians.
|
||||
*/
|
||||
const gfxMatrix& Rotate(gfxFloat radians) {
|
||||
// cairo_matrix_rotate?
|
||||
gfxFloat s = sin(radians);
|
||||
gfxFloat c = cos(radians);
|
||||
gfxMatrix t( c, s,
|
||||
|
@ -123,27 +178,58 @@ public:
|
|||
return *this = t.Multiply(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the current matrix with m.
|
||||
* This is a post-multiplication, i.e. the transformations of m are
|
||||
* applied _after_ the existing transformations.
|
||||
*
|
||||
* XXX is that difference (compared to Rotate etc) a good thing?
|
||||
*/
|
||||
const gfxMatrix& Multiply(const gfxMatrix& m) {
|
||||
cairo_matrix_multiply(&mat, &mat, &m.mat);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TransformDistance(gfxFloat *dx, gfxFloat *dy) const {
|
||||
cairo_matrix_transform_distance(&mat, dx, dy);
|
||||
/**
|
||||
* Transforms a point according to this matrix.
|
||||
*/
|
||||
gfxPoint Transform(const gfxPoint point) const {
|
||||
gfxPoint ret = point;
|
||||
cairo_matrix_transform_point(&mat, &ret.x, &ret.y);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TransformPoint(gfxFloat *x, gfxFloat *y) const {
|
||||
cairo_matrix_transform_point(&mat, x, y);
|
||||
/**
|
||||
* Transform a distance according to this matrix. This does not apply
|
||||
* any translation components.
|
||||
*/
|
||||
gfxSize Transform(const gfxSize size) const {
|
||||
gfxSize ret = size;
|
||||
cairo_matrix_transform_distance(&mat, &ret.width, &ret.height);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms both the point and distance according to this matrix.
|
||||
*/
|
||||
gfxRect Transform(const gfxRect rect) const {
|
||||
gfxRect ret(Transform(rect.pos), Transform(rect.size));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// XXX this is wrong and should go away
|
||||
gfxSize GetScaling() const {
|
||||
return gfxSize(mat.xx, mat.yy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation component of this matrix.
|
||||
*/
|
||||
gfxPoint GetTranslation() const {
|
||||
return gfxPoint(mat.x0, mat.y0);
|
||||
}
|
||||
|
||||
// XXX this is wrong and should go away
|
||||
bool HasShear() const {
|
||||
return ((mat.xy != 0.0) || (mat.yx != 0.0));
|
||||
}
|
||||
|
|
|
@ -47,7 +47,19 @@ class gfxWindowsSurface : public gfxASurface {
|
|||
|
||||
public:
|
||||
gfxWindowsSurface(HDC dc);
|
||||
gfxWindowsSurface(HDC dc, unsigned long width, unsigned long height);
|
||||
gfxWindowsSurface(unsigned long width, unsigned long height);
|
||||
virtual ~gfxWindowsSurface();
|
||||
|
||||
|
||||
HDC GetDC() { return mDC; }
|
||||
private:
|
||||
PRBool mOwnsDC;
|
||||
HDC mDC;
|
||||
HBITMAP mOrigBitmap;
|
||||
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
};
|
||||
|
||||
#endif /* GFX_WINDOWSSURFACE_H */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -41,6 +42,7 @@
|
|||
#include "gfxASurface.h"
|
||||
|
||||
#include <cairo-xlib.h>
|
||||
#include <cairo-xlib-xrender.h>
|
||||
|
||||
class gfxXlibSurface : public gfxASurface {
|
||||
THEBES_DECL_ISUPPORTS_INHERITED
|
||||
|
@ -59,6 +61,12 @@ public:
|
|||
// for the default screen, and attach the given visual
|
||||
gfxXlibSurface(Display *dpy, Visual *visual, unsigned long width, unsigned long height);
|
||||
|
||||
gfxXlibSurface(Display* dpy, Drawable drawable, XRenderPictFormat *format,
|
||||
unsigned long width, unsigned long height);
|
||||
|
||||
gfxXlibSurface(Display* dpy, XRenderPictFormat *format,
|
||||
unsigned long width, unsigned long height);
|
||||
|
||||
virtual ~gfxXlibSurface();
|
||||
|
||||
unsigned long Width() { return mWidth; }
|
||||
|
@ -67,6 +75,8 @@ public:
|
|||
Display* XDisplay() { return mDisplay; }
|
||||
Drawable XDrawable() { return mDrawable; }
|
||||
|
||||
static XRenderPictFormat *FindRenderFormat(Display *dpy, gfxImageFormat format);
|
||||
|
||||
protected:
|
||||
PRBool mOwnsPixmap;
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ REQUIRES = \
|
|||
cairo \
|
||||
libpixman \
|
||||
string \
|
||||
xpcom
|
||||
xpcom \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
gfxContext.cpp \
|
||||
|
@ -31,6 +32,15 @@ ifeq ($(MOZ_GFX_TOOLKIT),gtk2)
|
|||
CPPSRCS += gfxXlibSurface.cpp
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_GLITZ
|
||||
REQUIRES += glitz
|
||||
CPPSRCS += gfxGlitzSurface.cpp
|
||||
|
||||
ifeq ($(MOZ_GFX_TOOLKIT),gtk2)
|
||||
REQUIRES += glitzglx
|
||||
endif
|
||||
endif
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
# This library is used by other shared libs in a static build
|
||||
FORCE_USE_PIC = 1
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@pavlov.net>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -120,40 +121,26 @@ void gfxContext::Line(gfxPoint start, gfxPoint end)
|
|||
LineTo(end);
|
||||
}
|
||||
|
||||
// XXX snapToPixels is only valid when snapping for filled
|
||||
// rectangles and for even-width stroked rectangles.
|
||||
// For odd-width stroked rectangles, we need to offset x/y by
|
||||
// 0.5...
|
||||
void gfxContext::Rectangle(gfxRect rect, PRBool snapToPixels)
|
||||
{
|
||||
if (snapToPixels) {
|
||||
gfxPoint p1 = UserToDevice(rect.pos);
|
||||
gfxPoint p2 = UserToDevice(rect.pos + rect.size);
|
||||
gfxRect snappedRect(rect);
|
||||
|
||||
gfxPoint p3 = UserToDevice(rect.pos + gfxSize(rect.size.width, 0.0));
|
||||
gfxPoint p4 = UserToDevice(rect.pos + gfxSize(0.0, rect.size.height));
|
||||
if (UserToDevicePixelSnapped(snappedRect)) {
|
||||
cairo_matrix_t mat;
|
||||
cairo_get_matrix(mCairo, &mat);
|
||||
cairo_identity_matrix(mCairo);
|
||||
Rectangle(snappedRect);
|
||||
cairo_set_matrix(mCairo, &mat);
|
||||
|
||||
if (p1.x != p4.x ||
|
||||
p2.x != p3.x ||
|
||||
p1.y != p3.y ||
|
||||
p2.y != p4.y)
|
||||
// rectangle is no longer axis-aligned after transforming, so don't snap
|
||||
goto dontsnap;
|
||||
|
||||
cairo_matrix_t mat;
|
||||
cairo_get_matrix(mCairo, &mat);
|
||||
|
||||
if (mat.xx != 1.0 ||
|
||||
mat.yy != 1.0)
|
||||
// if we're not at 1.0 scale, don't snap
|
||||
goto dontsnap;
|
||||
|
||||
p1.round();
|
||||
p2.round();
|
||||
|
||||
cairo_identity_matrix(mCairo);
|
||||
cairo_rectangle(mCairo, p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
|
||||
cairo_set_matrix(mCairo, &mat);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dontsnap:
|
||||
cairo_rectangle(mCairo, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
|
||||
}
|
||||
|
||||
|
@ -297,6 +284,69 @@ gfxRect gfxContext::UserToDevice(gfxRect rect) const
|
|||
return ret;
|
||||
}
|
||||
|
||||
PRBool gfxContext::UserToDevicePixelSnapped(gfxRect& rect) const
|
||||
{
|
||||
// if we're not at 1.0 scale, don't snap
|
||||
cairo_matrix_t mat;
|
||||
cairo_get_matrix(mCairo, &mat);
|
||||
if (mat.xx != 1.0 || mat.yy != 1.0)
|
||||
return PR_FALSE;
|
||||
|
||||
gfxPoint p1 = UserToDevice(rect.pos);
|
||||
gfxPoint p2 = UserToDevice(rect.pos + rect.size);
|
||||
|
||||
gfxPoint p3 = UserToDevice(rect.pos + gfxSize(rect.size.width, 0.0));
|
||||
gfxPoint p4 = UserToDevice(rect.pos + gfxSize(0.0, rect.size.height));
|
||||
|
||||
// rectangle is no longer axis-aligned after transforming, so we can't snap
|
||||
if (p1.x != p4.x ||
|
||||
p2.x != p3.x ||
|
||||
p1.y != p3.y ||
|
||||
p2.y != p4.y)
|
||||
return PR_FALSE;
|
||||
|
||||
p1.round();
|
||||
p2.round();
|
||||
|
||||
gfxPoint pd = p2 - p1;
|
||||
|
||||
rect.pos = p1;
|
||||
rect.size = gfxSize(pd.x, pd.y);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void gfxContext::PixelSnappedRectangleAndSetPattern(const gfxRect& rect,
|
||||
gfxPattern *pattern)
|
||||
{
|
||||
gfxRect r(rect);
|
||||
|
||||
// Bob attempts to pixel-snap the rectangle, and returns true if
|
||||
// the snapping succeeds. If it does, we need to set up an
|
||||
// identity matrix, because the rectangle given back is in device
|
||||
// coordinates.
|
||||
//
|
||||
// We then have to call a translate to dr.pos afterwards, to make
|
||||
// sure the image lines up in the right place with our pixel
|
||||
// snapped rectangle.
|
||||
//
|
||||
// If snapping wasn't successful, we just translate to where the
|
||||
// pattern would normally start (in app coordinates) and do the
|
||||
// same thing.
|
||||
|
||||
gfxMatrix mat = CurrentMatrix();
|
||||
if (UserToDevicePixelSnapped(r)) {
|
||||
IdentityMatrix();
|
||||
}
|
||||
|
||||
Translate(r.pos);
|
||||
r.pos.x = r.pos.y = 0;
|
||||
Rectangle(r);
|
||||
SetPattern(pattern);
|
||||
|
||||
SetMatrix(mat);
|
||||
}
|
||||
|
||||
void gfxContext::SetAntialiasMode(AntialiasMode mode)
|
||||
{
|
||||
// XXX implement me
|
||||
|
@ -418,6 +468,18 @@ void gfxContext::SetSource(gfxASurface *surface, gfxPoint offset)
|
|||
cairo_set_source_surface(mCairo, surface->CairoSurface(), offset.x, offset.y);
|
||||
}
|
||||
|
||||
// masking
|
||||
|
||||
void gfxContext::Mask(gfxPattern *pattern)
|
||||
{
|
||||
cairo_mask(mCairo, pattern->CairoPattern());
|
||||
}
|
||||
|
||||
void gfxContext::Mask(gfxASurface *surface, gfxPoint offset)
|
||||
{
|
||||
cairo_mask_surface(mCairo, surface->CairoSurface(), offset.x, offset.y);
|
||||
}
|
||||
|
||||
// fonts?
|
||||
void gfxContext::DrawString(gfxTextRun& text, int pos, int len)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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 thebes
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* 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 "gfxGlitzSurface.h"
|
||||
|
||||
THEBES_IMPL_REFCOUNTING(gfxGlitzSurface)
|
||||
|
||||
gfxGlitzSurface::gfxGlitzSurface(glitz_drawable_t *drawable, glitz_surface_t *surface, PRBool takeOwnership)
|
||||
: mGlitzDrawable (drawable), mGlitzSurface(surface), mOwnsSurface(takeOwnership)
|
||||
{
|
||||
cairo_surface_t *surf = cairo_glitz_surface_create (mGlitzSurface);
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxGlitzSurface::~gfxGlitzSurface()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (mOwnsSurface) {
|
||||
if (mGlitzSurface) {
|
||||
glitz_surface_flush(mGlitzSurface);
|
||||
glitz_surface_destroy(mGlitzSurface);
|
||||
}
|
||||
|
||||
if (mGlitzDrawable) {
|
||||
glitz_drawable_flush(mGlitzDrawable);
|
||||
glitz_drawable_finish(mGlitzDrawable);
|
||||
glitz_drawable_destroy(mGlitzDrawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxGlitzSurface::SwapBuffers()
|
||||
{
|
||||
glitz_drawable_swap_buffers (GlitzDrawable());
|
||||
}
|
||||
|
||||
unsigned long
|
||||
gfxGlitzSurface::Width()
|
||||
{
|
||||
return glitz_drawable_get_width (GlitzDrawable());
|
||||
}
|
||||
|
||||
unsigned long
|
||||
gfxGlitzSurface::Height()
|
||||
{
|
||||
return glitz_drawable_get_height (GlitzDrawable());
|
||||
}
|
|
@ -39,11 +39,44 @@
|
|||
|
||||
THEBES_IMPL_REFCOUNTING(gfxWindowsSurface)
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc)
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc) :
|
||||
mOwnsDC(PR_FALSE), mDC(dc), mOrigBitmap(nsnull)
|
||||
{
|
||||
Init(cairo_win32_surface_create(dc));
|
||||
Init(cairo_win32_surface_create(mDC));
|
||||
}
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(HDC dc, unsigned long width, unsigned long height) :
|
||||
mOwnsDC(PR_TRUE), mWidth(width), mHeight(height)
|
||||
{
|
||||
mDC = CreateCompatibleDC(dc);
|
||||
|
||||
HBITMAP tbits = nsnull;
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
tbits = CreateCompatibleBitmap(dc, width, height);
|
||||
else
|
||||
tbits = CreateCompatibleBitmap(dc, 2, 2);
|
||||
|
||||
mOrigBitmap = (HBITMAP)SelectObject(mDC, tbits);
|
||||
|
||||
Init(cairo_win32_surface_create(mDC));
|
||||
}
|
||||
|
||||
gfxWindowsSurface::gfxWindowsSurface(unsigned long width, unsigned long height)
|
||||
{
|
||||
// Init(cairo_win32_surface_create(dc));
|
||||
}
|
||||
|
||||
gfxWindowsSurface::~gfxWindowsSurface()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (mDC && mOrigBitmap) {
|
||||
HBITMAP tbits = (HBITMAP)SelectObject(mDC, mOrigBitmap);
|
||||
if (tbits)
|
||||
DeleteObject(tbits);
|
||||
}
|
||||
|
||||
if (mOwnsDC)
|
||||
DeleteDC(mDC);
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "gfxXlibSurface.h"
|
||||
|
||||
THEBES_IMPL_REFCOUNTING(gfxXlibSurface)
|
||||
|
||||
gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual) :
|
||||
mOwnsPixmap(PR_FALSE), mDisplay(dpy), mDrawable(drawable)
|
||||
gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual)
|
||||
: mOwnsPixmap(PR_FALSE), mDisplay(dpy), mDrawable(drawable)
|
||||
{
|
||||
// figure out width/height/depth
|
||||
Window root_ignore;
|
||||
|
@ -62,15 +63,15 @@ gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual)
|
|||
}
|
||||
|
||||
gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual,
|
||||
unsigned long width, unsigned long height) :
|
||||
mOwnsPixmap(PR_FALSE), mDisplay(dpy), mDrawable(drawable), mWidth(width), mHeight(height)
|
||||
unsigned long width, unsigned long height)
|
||||
: mOwnsPixmap(PR_FALSE), mDisplay(dpy), mDrawable(drawable), mWidth(width), mHeight(height)
|
||||
{
|
||||
cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, width, height);
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxXlibSurface::gfxXlibSurface(Display* dpy, Visual* visual, unsigned long width, unsigned long height) :
|
||||
mOwnsPixmap(PR_TRUE), mDisplay(dpy), mWidth(width), mHeight(height)
|
||||
gfxXlibSurface::gfxXlibSurface(Display* dpy, Visual* visual, unsigned long width, unsigned long height)
|
||||
: mOwnsPixmap(PR_TRUE), mDisplay(dpy), mWidth(width), mHeight(height)
|
||||
|
||||
{
|
||||
mDrawable = (Drawable)XCreatePixmap(dpy,
|
||||
|
@ -82,6 +83,32 @@ gfxXlibSurface::gfxXlibSurface(Display* dpy, Visual* visual, unsigned long width
|
|||
Init(surf);
|
||||
}
|
||||
|
||||
gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, XRenderPictFormat *format,
|
||||
unsigned long width, unsigned long height)
|
||||
: mOwnsPixmap(PR_FALSE), mDisplay(dpy), mDrawable(drawable),
|
||||
mWidth(width), mHeight(height)
|
||||
{
|
||||
cairo_surface_t *surf = cairo_xlib_surface_create_with_xrender_format (dpy, drawable,
|
||||
ScreenOfDisplay(dpy,DefaultScreen(dpy)),
|
||||
format, width, height);
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxXlibSurface::gfxXlibSurface(Display* dpy, XRenderPictFormat *format,
|
||||
unsigned long width, unsigned long height)
|
||||
: mOwnsPixmap(PR_TRUE), mDisplay(dpy), mWidth(width), mHeight(height)
|
||||
{
|
||||
mDrawable = (Drawable)XCreatePixmap(dpy,
|
||||
RootWindow(dpy, DefaultScreen(dpy)),
|
||||
width, height,
|
||||
format->depth);
|
||||
|
||||
cairo_surface_t *surf = cairo_xlib_surface_create_with_xrender_format (dpy, mDrawable,
|
||||
ScreenOfDisplay(dpy,DefaultScreen(dpy)),
|
||||
format, width, height);
|
||||
Init(surf);
|
||||
}
|
||||
|
||||
gfxXlibSurface::~gfxXlibSurface()
|
||||
{
|
||||
Destroy();
|
||||
|
@ -89,3 +116,24 @@ gfxXlibSurface::~gfxXlibSurface()
|
|||
if (mOwnsPixmap)
|
||||
XFreePixmap(mDisplay, mDrawable);
|
||||
}
|
||||
|
||||
XRenderPictFormat*
|
||||
gfxXlibSurface::FindRenderFormat(Display *dpy, gfxImageFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case ImageFormatARGB32:
|
||||
return XRenderFindStandardFormat (dpy, PictStandardARGB32);
|
||||
break;
|
||||
case ImageFormatRGB24:
|
||||
return XRenderFindStandardFormat (dpy, PictStandardRGB24);
|
||||
break;
|
||||
case ImageFormatA8:
|
||||
return XRenderFindStandardFormat (dpy, PictStandardA8);
|
||||
break;
|
||||
case ImageFormatA1:
|
||||
return XRenderFindStandardFormat (dpy, PictStandardA1);
|
||||
break;
|
||||
}
|
||||
|
||||
return (XRenderPictFormat*)NULL;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче