LCOV - code coverage report
Current view: directory - gfx/thebes - gfxPlatformGtk.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 143 23 16.1 %
Date: 2012-06-02 Functions: 20 4 20.0 %

       1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Foundation code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Mozilla Foundation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2005
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Vladimir Vukicevic <vladimir@pobox.com>
      23                 :  *   Masayuki Nakano <masayuki@d-toybox.com>
      24                 :  *   Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #ifdef MOZ_PANGO
      41                 : #define PANGO_ENABLE_BACKEND
      42                 : #define PANGO_ENABLE_ENGINE
      43                 : #endif
      44                 : 
      45                 : #include "gfxPlatformGtk.h"
      46                 : 
      47                 : #include "nsUnicharUtils.h"
      48                 : #include "nsUnicodeProperties.h"
      49                 : #include "gfxFontconfigUtils.h"
      50                 : #ifdef MOZ_PANGO
      51                 : #include "gfxPangoFonts.h"
      52                 : #include "gfxContext.h"
      53                 : #include "gfxUserFontSet.h"
      54                 : #else
      55                 : #include <ft2build.h>
      56                 : #include FT_FREETYPE_H
      57                 : #include "gfxFT2Fonts.h"
      58                 : #endif
      59                 : 
      60                 : #include "mozilla/gfx/2D.h"
      61                 : 
      62                 : #include "cairo.h"
      63                 : #include <gtk/gtk.h>
      64                 : 
      65                 : #include "gfxImageSurface.h"
      66                 : #ifdef MOZ_X11
      67                 : #include <gdk/gdkx.h>
      68                 : #include "gfxXlibSurface.h"
      69                 : #include "cairo-xlib.h"
      70                 : 
      71                 : /* Undefine the Status from Xlib since it will conflict with system headers on OSX */
      72                 : #if defined(__APPLE__) && defined(Status)
      73                 : #undef Status
      74                 : #endif
      75                 : 
      76                 : #endif /* MOZ_X11 */
      77                 : 
      78                 : #include <fontconfig/fontconfig.h>
      79                 : 
      80                 : #include "nsMathUtils.h"
      81                 : 
      82                 : #define GDK_PIXMAP_SIZE_MAX 32767
      83                 : 
      84                 : using namespace mozilla;
      85                 : using namespace mozilla::gfx;
      86                 : using namespace mozilla::unicode;
      87                 : 
      88                 : gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
      89                 : 
      90                 : #ifndef MOZ_PANGO
      91                 : typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
      92                 : typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > PrefFontTable;
      93                 : static FontTable *gPlatformFonts = NULL;
      94                 : static FontTable *gPlatformFontAliases = NULL;
      95                 : static PrefFontTable *gPrefFonts = NULL;
      96                 : static gfxSparseBitSet *gCodepointsWithNoFonts = NULL;
      97                 : static FT_Library gPlatformFTLibrary = NULL;
      98                 : #endif
      99                 : 
     100                 : static cairo_user_data_key_t cairo_gdk_drawable_key;
     101               0 : static void do_gdk_drawable_unref (void *data)
     102                 : {
     103               0 :     GdkDrawable *d = (GdkDrawable*) data;
     104               0 :     g_object_unref (d);
     105               0 : }
     106                 : 
     107               3 : gfxPlatformGtk::gfxPlatformGtk()
     108                 : {
     109               3 :     if (!sFontconfigUtils)
     110               3 :         sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
     111                 : 
     112                 : #ifndef MOZ_PANGO
     113                 :     FT_Init_FreeType(&gPlatformFTLibrary);
     114                 : 
     115                 :     gPlatformFonts = new FontTable();
     116                 :     gPlatformFonts->Init(100);
     117                 :     gPlatformFontAliases = new FontTable();
     118                 :     gPlatformFontAliases->Init(100);
     119                 :     gPrefFonts = new PrefFontTable();
     120                 :     gPrefFonts->Init(100);
     121                 :     gCodepointsWithNoFonts = new gfxSparseBitSet();
     122                 :     UpdateFontList();
     123                 : #endif
     124               3 : }
     125                 : 
     126               9 : gfxPlatformGtk::~gfxPlatformGtk()
     127                 : {
     128               3 :     gfxFontconfigUtils::Shutdown();
     129               3 :     sFontconfigUtils = nsnull;
     130                 : 
     131                 : #ifdef MOZ_PANGO
     132               3 :     gfxPangoFontGroup::Shutdown();
     133                 : #else
     134                 :     delete gPlatformFonts;
     135                 :     gPlatformFonts = NULL;
     136                 :     delete gPlatformFontAliases;
     137                 :     gPlatformFontAliases = NULL;
     138                 :     delete gPrefFonts;
     139                 :     gPrefFonts = NULL;
     140                 :     delete gCodepointsWithNoFonts;
     141                 :     gCodepointsWithNoFonts = NULL;
     142                 : 
     143                 : #ifdef NS_FREE_PERMANENT_DATA
     144                 :     // do cairo cleanup *before* closing down the FTLibrary,
     145                 :     // otherwise we'll crash when the gfxPlatform destructor
     146                 :     // calls it (bug 605009)
     147                 :     cairo_debug_reset_static_data();
     148                 : 
     149                 :     FT_Done_FreeType(gPlatformFTLibrary);
     150                 :     gPlatformFTLibrary = NULL;
     151                 : #endif
     152                 : #endif
     153                 : 
     154                 : #if 0
     155                 :     // It would be nice to do this (although it might need to be after
     156                 :     // the cairo shutdown that happens in ~gfxPlatform).  It even looks
     157                 :     // idempotent.  But it has fatal assertions that fire if stuff is
     158                 :     // leaked, and we hit them.
     159                 :     FcFini();
     160                 : #endif
     161              12 : }
     162                 : 
     163                 : already_AddRefed<gfxASurface>
     164              17 : gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
     165                 :                                        gfxASurface::gfxContentType contentType)
     166                 : {
     167              34 :     nsRefPtr<gfxASurface> newSurface;
     168              17 :     bool needsClear = true;
     169              17 :     gfxASurface::gfxImageFormat imageFormat = gfxASurface::FormatFromContent(contentType);
     170                 : #ifdef MOZ_X11
     171                 :     // XXX we really need a different interface here, something that passes
     172                 :     // in more context, including the display and/or target surface type that
     173                 :     // we should try to match
     174              17 :     GdkScreen *gdkScreen = gdk_screen_get_default();
     175              17 :     if (gdkScreen) {
     176                 :         // try to optimize it for 16bpp default screen
     177               0 :         if (gfxASurface::CONTENT_COLOR == contentType) {
     178               0 :             imageFormat = GetOffscreenFormat();
     179                 :         }
     180                 : 
     181               0 :         if (UseClientSideRendering()) {
     182                 :             // We're not going to use XRender, so we don't need to
     183                 :             // search for a render format
     184               0 :             newSurface = new gfxImageSurface(size, imageFormat);
     185                 :             // The gfxImageSurface ctor zeroes this for us, no need to
     186                 :             // waste time clearing again
     187               0 :             needsClear = false;
     188                 :         } else {
     189               0 :             Screen *screen = gdk_x11_screen_get_xscreen(gdkScreen);
     190                 :             XRenderPictFormat* xrenderFormat =
     191                 :                 gfxXlibSurface::FindRenderFormat(DisplayOfScreen(screen),
     192               0 :                                                  imageFormat);
     193                 : 
     194               0 :             if (xrenderFormat) {
     195               0 :                 newSurface = gfxXlibSurface::Create(screen, xrenderFormat, size);
     196                 :             }
     197                 :         }
     198                 :     }
     199                 : #endif
     200                 : 
     201              17 :     if (!newSurface) {
     202                 :         // We couldn't create a native surface for whatever reason;
     203                 :         // e.g., no display, no RENDER, bad size, etc.
     204                 :         // Fall back to image surface for the data.
     205              17 :         newSurface = new gfxImageSurface(size, imageFormat);
     206                 :     }
     207                 : 
     208              17 :     if (newSurface->CairoStatus()) {
     209               0 :         newSurface = nsnull; // surface isn't valid for some reason
     210                 :     }
     211                 : 
     212              17 :     if (newSurface && needsClear) {
     213              34 :         gfxContext tmpCtx(newSurface);
     214              17 :         tmpCtx.SetOperator(gfxContext::OPERATOR_CLEAR);
     215              17 :         tmpCtx.Paint();
     216                 :     }
     217                 : 
     218              17 :     return newSurface.forget();
     219                 : }
     220                 : 
     221                 : #ifdef MOZ_PANGO
     222                 : 
     223                 : nsresult
     224               0 : gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
     225                 :                             const nsACString& aGenericFamily,
     226                 :                             nsTArray<nsString>& aListOfFonts)
     227                 : {
     228                 :     return sFontconfigUtils->GetFontList(aLangGroup, aGenericFamily,
     229               0 :                                          aListOfFonts);
     230                 : }
     231                 : 
     232                 : nsresult
     233               0 : gfxPlatformGtk::UpdateFontList()
     234                 : {
     235               0 :     return sFontconfigUtils->UpdateFontList();
     236                 : }
     237                 : 
     238                 : nsresult
     239               0 : gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
     240                 :                                 FontResolverCallback aCallback,
     241                 :                                 void *aClosure,
     242                 :                                 bool& aAborted)
     243                 : {
     244                 :     return sFontconfigUtils->ResolveFontName(aFontName, aCallback,
     245               0 :                                              aClosure, aAborted);
     246                 : }
     247                 : 
     248                 : nsresult
     249               0 : gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
     250                 : {
     251               0 :     return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
     252                 : }
     253                 : 
     254                 : gfxFontGroup *
     255               0 : gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
     256                 :                                 const gfxFontStyle *aStyle,
     257                 :                                 gfxUserFontSet *aUserFontSet)
     258                 : {
     259               0 :     return new gfxPangoFontGroup(aFamilies, aStyle, aUserFontSet);
     260                 : }
     261                 : 
     262                 : gfxFontEntry*
     263               0 : gfxPlatformGtk::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
     264                 :                                 const nsAString& aFontName)
     265                 : {
     266               0 :     return gfxPangoFontGroup::NewFontEntry(*aProxyEntry, aFontName);
     267                 : }
     268                 : 
     269                 : gfxFontEntry* 
     270               0 : gfxPlatformGtk::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, 
     271                 :                                  const PRUint8 *aFontData, PRUint32 aLength)
     272                 : {
     273                 :     // passing ownership of the font data to the new font entry
     274                 :     return gfxPangoFontGroup::NewFontEntry(*aProxyEntry,
     275               0 :                                            aFontData, aLength);
     276                 : }
     277                 : 
     278                 : bool
     279               0 : gfxPlatformGtk::IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags)
     280                 : {
     281                 :     // check for strange format flags
     282               0 :     NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED),
     283                 :                  "strange font format hint set");
     284                 : 
     285                 :     // accept supported formats
     286                 :     // Pango doesn't apply features from AAT TrueType extensions.
     287                 :     // Assume that if this is the only SFNT format specified,
     288                 :     // then AAT extensions are required for complex script support.
     289               0 :     if (aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_WOFF     |
     290                 :                         gfxUserFontSet::FLAG_FORMAT_OPENTYPE | 
     291                 :                         gfxUserFontSet::FLAG_FORMAT_TRUETYPE)) {
     292               0 :         return true;
     293                 :     }
     294                 : 
     295                 :     // reject all other formats, known and unknown
     296               0 :     if (aFormatFlags != 0) {
     297               0 :         return false;
     298                 :     }
     299                 : 
     300                 :     // no format hint set, need to look at data
     301               0 :     return true;
     302                 : }
     303                 : 
     304                 : #else
     305                 : 
     306                 : nsresult
     307                 : gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
     308                 :                             const nsACString& aGenericFamily,
     309                 :                             nsTArray<nsString>& aListOfFonts)
     310                 : {
     311                 :     return sFontconfigUtils->GetFontList(aLangGroup, aGenericFamily,
     312                 :                                          aListOfFonts);
     313                 : }
     314                 : 
     315                 : nsresult
     316                 : gfxPlatformGtk::UpdateFontList()
     317                 : {
     318                 :     FcPattern *pat = NULL;
     319                 :     FcObjectSet *os = NULL;
     320                 :     FcFontSet *fs = NULL;
     321                 :     PRInt32 result = -1;
     322                 : 
     323                 :     pat = FcPatternCreate();
     324                 :     os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, NULL);
     325                 : 
     326                 :     fs = FcFontList(NULL, pat, os);
     327                 : 
     328                 : 
     329                 :     for (int i = 0; i < fs->nfont; i++) {
     330                 :         char *str;
     331                 : 
     332                 :         if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
     333                 :             continue;
     334                 : 
     335                 :         //printf("Family: %s\n", str);
     336                 : 
     337                 :         nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
     338                 :         nsAutoString key(name);
     339                 :         ToLowerCase(key);
     340                 :         nsRefPtr<FontFamily> ff;
     341                 :         if (!gPlatformFonts->Get(key, &ff)) {
     342                 :             ff = new FontFamily(name);
     343                 :             gPlatformFonts->Put(key, ff);
     344                 :         }
     345                 : 
     346                 :         FontEntry *fe = new FontEntry(ff->Name());
     347                 :         ff->AddFontEntry(fe);
     348                 : 
     349                 :         if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
     350                 :             fe->mFilename = nsDependentCString(str);
     351                 :             //printf(" - file: %s\n", str);
     352                 :         }
     353                 : 
     354                 :         int x;
     355                 :         if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
     356                 :             //printf(" - index: %d\n", x);
     357                 :             fe->mFTFontIndex = x;
     358                 :         } else {
     359                 :             fe->mFTFontIndex = 0;
     360                 :         }
     361                 : 
     362                 :         fe->mWeight = gfxFontconfigUtils::GetThebesWeight(fs->fonts[i]);
     363                 :         //printf(" - weight: %d\n", fe->mWeight);
     364                 : 
     365                 :         fe->mItalic = false;
     366                 :         if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
     367                 :             switch (x) {
     368                 :             case FC_SLANT_ITALIC:
     369                 :             case FC_SLANT_OBLIQUE:
     370                 :                 fe->mItalic = true;
     371                 :             }
     372                 :             //printf(" - slant: %d\n", x);
     373                 :         }
     374                 : 
     375                 :         //if (FcPatternGetInteger(fs->fonts[i], FC_WIDTH, 0, &x) == FcResultMatch)
     376                 :             //printf(" - width: %d\n", x);
     377                 :         // XXX deal with font-stretch stuff later
     378                 :     }
     379                 : 
     380                 :     if (pat)
     381                 :         FcPatternDestroy(pat);
     382                 :     if (os)
     383                 :         FcObjectSetDestroy(os);
     384                 :     if (fs)
     385                 :         FcFontSetDestroy(fs);
     386                 : 
     387                 :     return sFontconfigUtils->UpdateFontList();
     388                 : }
     389                 : 
     390                 : nsresult
     391                 : gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
     392                 :                                 FontResolverCallback aCallback,
     393                 :                                 void *aClosure,
     394                 :                                 bool& aAborted)
     395                 : {
     396                 : 
     397                 :     nsAutoString name(aFontName);
     398                 :     ToLowerCase(name);
     399                 : 
     400                 :     nsRefPtr<FontFamily> ff;
     401                 :     if (gPlatformFonts->Get(name, &ff) ||
     402                 :         gPlatformFontAliases->Get(name, &ff)) {
     403                 :         aAborted = !(*aCallback)(ff->Name(), aClosure);
     404                 :         return NS_OK;
     405                 :     }
     406                 : 
     407                 :     nsCAutoString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
     408                 : 
     409                 :     FcPattern *npat = FcPatternCreate();
     410                 :     FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
     411                 :     FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, NULL);
     412                 :     FcFontSet *nfs = FcFontList(NULL, npat, nos);
     413                 : 
     414                 :     for (int k = 0; k < nfs->nfont; k++) {
     415                 :         FcChar8 *str;
     416                 :         if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
     417                 :             continue;
     418                 :         nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
     419                 :         ToLowerCase(altName);
     420                 :         if (gPlatformFonts->Get(altName, &ff)) {
     421                 :             //printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
     422                 :             gPlatformFontAliases->Put(name, ff);
     423                 :             aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
     424                 :             goto DONE;
     425                 :         }
     426                 :     }
     427                 : 
     428                 :     FcPatternDestroy(npat);
     429                 :     FcObjectSetDestroy(nos);
     430                 :     FcFontSetDestroy(nfs);
     431                 : 
     432                 :     {
     433                 :     npat = FcPatternCreate();
     434                 :     FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
     435                 :     FcPatternDel(npat, FC_LANG);
     436                 :     FcConfigSubstitute(NULL, npat, FcMatchPattern);
     437                 :     FcDefaultSubstitute(npat);
     438                 : 
     439                 :     nos = FcObjectSetBuild(FC_FAMILY, NULL);
     440                 :     nfs = FcFontList(NULL, npat, nos);
     441                 : 
     442                 :     FcResult fresult;
     443                 : 
     444                 :     FcPattern *match = FcFontMatch(NULL, npat, &fresult);
     445                 :     if (match)
     446                 :         FcFontSetAdd(nfs, match);
     447                 : 
     448                 :     for (int k = 0; k < nfs->nfont; k++) {
     449                 :         FcChar8 *str;
     450                 :         if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
     451                 :             continue;
     452                 :         nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
     453                 :         ToLowerCase(altName);
     454                 :         if (gPlatformFonts->Get(altName, &ff)) {
     455                 :             //printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
     456                 :             gPlatformFontAliases->Put(name, ff);
     457                 :             aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
     458                 :             goto DONE;
     459                 :         }
     460                 :     }
     461                 :     }
     462                 :  DONE:
     463                 :     FcPatternDestroy(npat);
     464                 :     FcObjectSetDestroy(nos);
     465                 :     FcFontSetDestroy(nfs);
     466                 : 
     467                 :     return NS_OK;
     468                 : }
     469                 : 
     470                 : nsresult
     471                 : gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
     472                 : {
     473                 :     return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
     474                 : }
     475                 : 
     476                 : gfxFontGroup *
     477                 : gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
     478                 :                                 const gfxFontStyle *aStyle,
     479                 :                                 gfxUserFontSet *aUserFontSet)
     480                 : {
     481                 :     return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
     482                 : }
     483                 : 
     484                 : #endif
     485                 : 
     486                 : static PRInt32 sDPI = 0;
     487                 : 
     488                 : PRInt32
     489               0 : gfxPlatformGtk::GetDPI()
     490                 : {
     491               0 :     if (!sDPI) {
     492                 :         // Make sure init is run so we have a resolution
     493               0 :         GdkScreen *screen = gdk_screen_get_default();
     494               0 :         gtk_settings_get_for_screen(screen);
     495               0 :         sDPI = PRInt32(round(gdk_screen_get_resolution(screen)));
     496               0 :         if (sDPI <= 0) {
     497                 :             // Fall back to something sane
     498               0 :             sDPI = 96;
     499                 :         }
     500                 :     }
     501               0 :     return sDPI;
     502                 : }
     503                 : 
     504                 : gfxImageFormat
     505               0 : gfxPlatformGtk::GetOffscreenFormat()
     506                 : {
     507               0 :     if (gdk_visual_get_system()->depth == 16) {
     508               0 :         return gfxASurface::ImageFormatRGB16_565;
     509                 :     }
     510                 : 
     511               0 :     return gfxASurface::ImageFormatRGB24;
     512                 : }
     513                 : 
     514                 : qcms_profile *
     515               0 : gfxPlatformGtk::GetPlatformCMSOutputProfile()
     516                 : {
     517                 : #ifdef MOZ_X11
     518               0 :     const char EDID1_ATOM_NAME[] = "XFree86_DDC_EDID1_RAWDATA";
     519               0 :     const char ICC_PROFILE_ATOM_NAME[] = "_ICC_PROFILE";
     520                 : 
     521                 :     Atom edidAtom, iccAtom;
     522               0 :     Display *dpy = GDK_DISPLAY();
     523               0 :     Window root = gdk_x11_get_default_root_xwindow();
     524                 : 
     525                 :     Atom retAtom;
     526                 :     int retFormat;
     527                 :     unsigned long retLength, retAfter;
     528                 :     unsigned char *retProperty ;
     529                 : 
     530               0 :     iccAtom = XInternAtom(dpy, ICC_PROFILE_ATOM_NAME, TRUE);
     531               0 :     if (iccAtom) {
     532                 :         // read once to get size, once for the data
     533               0 :         if (Success == XGetWindowProperty(dpy, root, iccAtom,
     534                 :                                           0, 0 /* length */,
     535                 :                                           False, AnyPropertyType,
     536                 :                                           &retAtom, &retFormat, &retLength,
     537               0 :                                           &retAfter, &retProperty)) {
     538                 :             XGetWindowProperty(dpy, root, iccAtom,
     539                 :                                0, retLength,
     540                 :                                False, AnyPropertyType,
     541                 :                                &retAtom, &retFormat, &retLength,
     542               0 :                                &retAfter, &retProperty);
     543                 : 
     544               0 :             qcms_profile* profile = NULL;
     545                 : 
     546               0 :             if (retLength > 0)
     547               0 :                 profile = qcms_profile_from_memory(retProperty, retLength);
     548                 : 
     549               0 :             XFree(retProperty);
     550                 : 
     551               0 :             if (profile) {
     552                 : #ifdef DEBUG_tor
     553                 :                 fprintf(stderr,
     554                 :                         "ICM profile read from %s successfully\n",
     555                 :                         ICC_PROFILE_ATOM_NAME);
     556                 : #endif
     557               0 :                 return profile;
     558                 :             }
     559                 :         }
     560                 :     }
     561                 : 
     562               0 :     edidAtom = XInternAtom(dpy, EDID1_ATOM_NAME, TRUE);
     563               0 :     if (edidAtom) {
     564               0 :         if (Success == XGetWindowProperty(dpy, root, edidAtom, 0, 32,
     565                 :                                           False, AnyPropertyType,
     566                 :                                           &retAtom, &retFormat, &retLength,
     567               0 :                                           &retAfter, &retProperty)) {
     568                 :             double gamma;
     569                 :             qcms_CIE_xyY whitePoint;
     570                 :             qcms_CIE_xyYTRIPLE primaries;
     571                 : 
     572               0 :             if (retLength != 128) {
     573                 : #ifdef DEBUG_tor
     574                 :                 fprintf(stderr, "Short EDID data\n");
     575                 : #endif
     576               0 :                 return nsnull;
     577                 :             }
     578                 : 
     579                 :             // Format documented in "VESA E-EDID Implementation Guide"
     580                 : 
     581               0 :             gamma = (100 + retProperty[0x17]) / 100.0;
     582               0 :             whitePoint.x = ((retProperty[0x21] << 2) |
     583               0 :                             (retProperty[0x1a] >> 2 & 3)) / 1024.0;
     584               0 :             whitePoint.y = ((retProperty[0x22] << 2) |
     585               0 :                             (retProperty[0x1a] >> 0 & 3)) / 1024.0;
     586               0 :             whitePoint.Y = 1.0;
     587                 : 
     588               0 :             primaries.red.x = ((retProperty[0x1b] << 2) |
     589               0 :                                (retProperty[0x19] >> 6 & 3)) / 1024.0;
     590               0 :             primaries.red.y = ((retProperty[0x1c] << 2) |
     591               0 :                                (retProperty[0x19] >> 4 & 3)) / 1024.0;
     592               0 :             primaries.red.Y = 1.0;
     593                 : 
     594               0 :             primaries.green.x = ((retProperty[0x1d] << 2) |
     595               0 :                                  (retProperty[0x19] >> 2 & 3)) / 1024.0;
     596               0 :             primaries.green.y = ((retProperty[0x1e] << 2) |
     597               0 :                                  (retProperty[0x19] >> 0 & 3)) / 1024.0;
     598               0 :             primaries.green.Y = 1.0;
     599                 : 
     600               0 :             primaries.blue.x = ((retProperty[0x1f] << 2) |
     601               0 :                                (retProperty[0x1a] >> 6 & 3)) / 1024.0;
     602               0 :             primaries.blue.y = ((retProperty[0x20] << 2) |
     603               0 :                                (retProperty[0x1a] >> 4 & 3)) / 1024.0;
     604               0 :             primaries.blue.Y = 1.0;
     605                 : 
     606               0 :             XFree(retProperty);
     607                 : 
     608                 : #ifdef DEBUG_tor
     609                 :             fprintf(stderr, "EDID gamma: %f\n", gamma);
     610                 :             fprintf(stderr, "EDID whitepoint: %f %f %f\n",
     611                 :                     whitePoint.x, whitePoint.y, whitePoint.Y);
     612                 :             fprintf(stderr, "EDID primaries: [%f %f %f] [%f %f %f] [%f %f %f]\n",
     613                 :                     primaries.Red.x, primaries.Red.y, primaries.Red.Y,
     614                 :                     primaries.Green.x, primaries.Green.y, primaries.Green.Y,
     615                 :                     primaries.Blue.x, primaries.Blue.y, primaries.Blue.Y);
     616                 : #endif
     617                 : 
     618                 :             qcms_profile* profile =
     619               0 :                 qcms_profile_create_rgb_with_gamma(whitePoint, primaries, gamma);
     620                 : 
     621                 : #ifdef DEBUG_tor
     622                 :             if (profile) {
     623                 :                 fprintf(stderr,
     624                 :                         "ICM profile read from %s successfully\n",
     625                 :                         EDID1_ATOM_NAME);
     626                 :             }
     627                 : #endif
     628                 : 
     629               0 :             return profile;
     630                 :         }
     631                 :     }
     632                 : #endif
     633                 : 
     634               0 :     return nsnull;
     635                 : }
     636                 : 
     637                 : 
     638                 : #ifndef MOZ_PANGO
     639                 : FT_Library
     640                 : gfxPlatformGtk::GetFTLibrary()
     641                 : {
     642                 :     return gPlatformFTLibrary;
     643                 : }
     644                 : 
     645                 : FontFamily *
     646                 : gfxPlatformGtk::FindFontFamily(const nsAString& aName)
     647                 : {
     648                 :     nsAutoString name(aName);
     649                 :     ToLowerCase(name);
     650                 : 
     651                 :     nsRefPtr<FontFamily> ff;
     652                 :     if (!gPlatformFonts->Get(name, &ff)) {
     653                 :         return nsnull;
     654                 :     }
     655                 :     return ff.get();
     656                 : }
     657                 : 
     658                 : FontEntry *
     659                 : gfxPlatformGtk::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
     660                 : {
     661                 :     nsRefPtr<FontFamily> ff = FindFontFamily(aName);
     662                 :     if (!ff)
     663                 :         return nsnull;
     664                 : 
     665                 :     return ff->FindFontEntry(aFontStyle);
     666                 : }
     667                 : 
     668                 : static PLDHashOperator
     669                 : FindFontForCharProc(nsStringHashKey::KeyType aKey,
     670                 :                     nsRefPtr<FontFamily>& aFontFamily,
     671                 :                     void* aUserArg)
     672                 : {
     673                 :     GlobalFontMatch *data = (GlobalFontMatch*)aUserArg;
     674                 :     aFontFamily->FindFontForChar(data);
     675                 :     return PL_DHASH_NEXT;
     676                 : }
     677                 : 
     678                 : already_AddRefed<gfxFont>
     679                 : gfxPlatformGtk::FindFontForChar(PRUint32 aCh, gfxFont *aFont)
     680                 : {
     681                 :     if (!gPlatformFonts || !gCodepointsWithNoFonts)
     682                 :         return nsnull;
     683                 : 
     684                 :     // is codepoint with no matching font? return null immediately
     685                 :     if (gCodepointsWithNoFonts->test(aCh)) {
     686                 :         return nsnull;
     687                 :     }
     688                 : 
     689                 :     GlobalFontMatch data(aCh, GetScriptCode(aCh),
     690                 :                          (aFont ? aFont->GetStyle() : nsnull));
     691                 : 
     692                 :     // find fonts that support the character
     693                 :     gPlatformFonts->Enumerate(FindFontForCharProc, &data);
     694                 : 
     695                 :     if (data.mBestMatch) {
     696                 :         nsRefPtr<gfxFT2Font> font =
     697                 :             gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
     698                 :                                       aFont->GetStyle()); 
     699                 :         gfxFont* ret = font.forget().get();
     700                 :         return already_AddRefed<gfxFont>(ret);
     701                 :     }
     702                 : 
     703                 :     // no match? add to set of non-matching codepoints
     704                 :     gCodepointsWithNoFonts->set(aCh);
     705                 : 
     706                 :     return nsnull;
     707                 : }
     708                 : 
     709                 : bool
     710                 : gfxPlatformGtk::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList)
     711                 : {
     712                 :     return gPrefFonts->Get(aKey, aFontEntryList);
     713                 : }
     714                 : 
     715                 : void
     716                 : gfxPlatformGtk::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList)
     717                 : {
     718                 :     gPrefFonts->Put(aKey, aFontEntryList);
     719                 : }
     720                 : #endif
     721                 : 
     722                 : 
     723                 : void
     724               0 : gfxPlatformGtk::SetGdkDrawable(gfxASurface *target,
     725                 :                                GdkDrawable *drawable)
     726                 : {
     727               0 :     if (target->CairoStatus())
     728               0 :         return;
     729                 : 
     730               0 :     g_object_ref(drawable);
     731                 : 
     732                 :     cairo_surface_set_user_data (target->CairoSurface(),
     733                 :                                  &cairo_gdk_drawable_key,
     734                 :                                  drawable,
     735               0 :                                  do_gdk_drawable_unref);
     736                 : }
     737                 : 
     738                 : GdkDrawable *
     739               0 : gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
     740                 : {
     741               0 :     if (target->CairoStatus())
     742               0 :         return NULL;
     743                 : 
     744                 :     GdkDrawable *result;
     745                 : 
     746                 :     result = (GdkDrawable*) cairo_surface_get_user_data (target->CairoSurface(),
     747               0 :                                                          &cairo_gdk_drawable_key);
     748               0 :     if (result)
     749               0 :         return result;
     750                 : 
     751                 : #ifdef MOZ_X11
     752               0 :     if (target->GetType() != gfxASurface::SurfaceTypeXlib)
     753               0 :         return NULL;
     754                 : 
     755               0 :     gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(target);
     756                 : 
     757                 :     // try looking it up in gdk's table
     758               0 :     result = (GdkDrawable*) gdk_xid_table_lookup(xs->XDrawable());
     759               0 :     if (result) {
     760               0 :         SetGdkDrawable(target, result);
     761               0 :         return result;
     762                 :     }
     763                 : #endif
     764                 : 
     765               0 :     return NULL;
     766                 : }
     767                 : 
     768                 : RefPtr<ScaledFont>
     769               0 : gfxPlatformGtk::GetScaledFontForFont(gfxFont *aFont)
     770                 : {
     771                 :   NativeFont nativeFont;
     772               0 :   nativeFont.mType = NATIVE_FONT_SKIA_FONT_FACE;
     773               0 :   nativeFont.mFont = aFont;
     774                 :   RefPtr<ScaledFont> scaledFont =
     775               0 :     Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
     776                 : 
     777                 :   return scaledFont;
     778                 : }
     779                 : 
     780                 : bool
     781               0 : gfxPlatformGtk::SupportsAzure(BackendType& aBackend)
     782                 : {
     783               0 :   aBackend = BACKEND_SKIA;
     784               0 :   return true;
     785                 : }
     786                 : 

Generated by: LCOV version 1.7