Advertisement
france00

libxft2.3.3-bgra-patch-ubuntu-20.04

Jun 5th, 2020
2,111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 21.13 KB | None | 0 0
  1. diff -up ../../xft-2.3.3/src/xftfreetype.c ./xftfreetype.c
  2. --- ../../xft-2.3.3/src/xftfreetype.c   2019-03-16 19:12:27.000000000 +0100
  3. +++ ./xftfreetype.c 2020-05-12 23:14:56.188927994 +0200
  4. @@ -514,7 +514,7 @@ XftFontInfoFill (Display *dpy, _Xconst F
  5.      /*
  6.       * Compute glyph load flags
  7.       */
  8. -    fi->load_flags = FT_LOAD_DEFAULT;
  9. +    fi->load_flags = FT_LOAD_DEFAULT | FT_LOAD_COLOR;
  10.  
  11.  #ifndef XFT_EMBEDDED_BITMAP
  12.  #define XFT_EMBEDDED_BITMAP "embeddedbitmap"
  13. @@ -766,6 +766,7 @@ XftFontOpenInfo (Display    *dpy,
  14.      FcChar32       hash_value;
  15.      FcChar32       rehash_value;
  16.      FcBool     antialias;
  17. +    FcBool     color;
  18.      int            max_glyph_memory;
  19.      int            alloc_size;
  20.      int            ascent, descent, height;
  21. @@ -822,12 +823,16 @@ XftFontOpenInfo (Display  *dpy,
  22.      if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
  23.     antialias = FcFalse;
  24.  
  25. +    color = FT_HAS_COLOR(face) ? FcTrue : FcFalse;
  26. +
  27.      /*
  28.       * Find the appropriate picture format
  29.       */
  30.      if (fi->render)
  31.      {
  32. -   if (antialias)
  33. +   if (color)
  34. +       format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
  35. +   else if (antialias)
  36.     {
  37.         switch (fi->rgba) {
  38.         case FC_RGBA_RGB:
  39. @@ -842,9 +847,7 @@ XftFontOpenInfo (Display    *dpy,
  40.         }
  41.     }
  42.     else
  43. -   {
  44.         format = XRenderFindStandardFormat (dpy, PictStandardA1);
  45. -   }
  46.  
  47.     if (!format)
  48.         goto bail2;
  49. @@ -959,6 +962,13 @@ XftFontOpenInfo (Display   *dpy,
  50.       * which doesn't happen in XftFontInfoFill
  51.       */
  52.      font->info.antialias = antialias;
  53. +
  54. +    /*
  55. +     * Set color value, which is only known once the
  56. +     * font was loaded
  57. +     */
  58. +    font->info.color = color;
  59. +
  60.      /*
  61.       * bump XftFile reference count
  62.       */
  63. diff -up ../../xft-2.3.3/src/xftglyphs.c ./xftglyphs.c
  64. --- ../../xft-2.3.3/src/xftglyphs.c 2019-03-16 19:12:27.000000000 +0100
  65. +++ ./xftglyphs.c   2020-05-12 23:27:36.291338870 +0200
  66. @@ -26,6 +26,8 @@
  67.  
  68.  #include FT_SYNTHESIS_H
  69.  
  70. +#include FT_GLYPH_H
  71. +
  72.  /*
  73.   * Validate the memory info for a font
  74.   */
  75. @@ -78,9 +80,11 @@ _XftFontValidateMemory (Display *dpy, Xf
  76.  static int
  77.  _compute_xrender_bitmap_size( FT_Bitmap*   target,
  78.                   FT_GlyphSlot  slot,
  79. -                 FT_Render_Mode    mode )
  80. +                 FT_Render_Mode    mode,
  81. +                 FT_Matrix*        matrix )
  82.  {
  83.      FT_Bitmap* ftbit;
  84. +    FT_Vector  vector;
  85.      int        width, height, pitch;
  86.  
  87.      if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
  88. @@ -91,6 +95,18 @@ _compute_xrender_bitmap_size( FT_Bitmap*
  89.  
  90.      width = ftbit->width;
  91.      height = ftbit->rows;
  92. +
  93. +
  94. +    if ( matrix && mode == FT_RENDER_MODE_NORMAL )
  95. +    {
  96. +   vector.x = ftbit->width;
  97. +   vector.y = ftbit->rows;
  98. +   FT_Vector_Transform(&vector, matrix);
  99. +
  100. +   width = (int)vector.x;
  101. +   height = (int)vector.y;
  102. +    }
  103. +
  104.      pitch = (width+3) & ~3;
  105.  
  106.      switch ( ftbit->pixel_mode )
  107. @@ -112,6 +128,10 @@ _compute_xrender_bitmap_size( FT_Bitmap*
  108.     }
  109.     break;
  110.  
  111. +    case FT_PIXEL_MODE_BGRA:
  112. +   pitch = width * 4;
  113. +   break;
  114. +
  115.      case FT_PIXEL_MODE_LCD:
  116.     if ( mode != FT_RENDER_MODE_LCD )
  117.         return -1;
  118. @@ -143,6 +163,105 @@ _compute_xrender_bitmap_size( FT_Bitmap*
  119.  }
  120.  
  121.  /* this functions converts the glyph bitmap found in a FT_GlyphSlot
  122. + * into a different format while scaling by applying the given matrix
  123. + * (see _compute_xrender_bitmap_size)
  124. + *
  125. + * you should call this function after _compute_xrender_bitmap_size
  126. + *
  127. + * target :: target bitmap descriptor. Note that its 'buffer' pointer
  128. + *           must point to memory allocated by the caller
  129. + *
  130. + * source :: the source bitmap descriptor
  131. + *
  132. + * matrix :: the scaling matrix to apply
  133. + */
  134. +static void
  135. +_scaled_fill_xrender_bitmap( FT_Bitmap*    target,
  136. +                    FT_Bitmap* source,
  137. +                             const FT_Matrix* matrix )
  138. +{
  139. +    unsigned char* src_buf   = source->buffer;
  140. +    unsigned char* dst_line  = target->buffer;
  141. +    int            src_pitch = source->pitch;
  142. +    int            width     = target->width;
  143. +    int            height    = target->rows;
  144. +    int            pitch     = target->pitch;
  145. +    int            h;
  146. +    FT_Vector      vector;
  147. +    FT_Matrix      inverse   = *matrix;
  148. +    int            sampling_width;
  149. +    int            sampling_height;
  150. +    int            sample_count;
  151. +
  152. +    if ( src_pitch < 0 )
  153. +   src_buf -= src_pitch*(source->rows-1);
  154. +
  155. +    FT_Matrix_Invert(&inverse);
  156. +
  157. +    /* compute how many source pixels a target pixel spans */
  158. +    vector.x = 1;
  159. +    vector.y = 1;
  160. +    FT_Vector_Transform(&vector, &inverse);
  161. +    sampling_width = vector.x / 2;
  162. +    sampling_height = vector.y / 2;
  163. +    sample_count = (2 * sampling_width + 1) * (2 * sampling_height + 1);
  164. +
  165. +    for    ( h = height; h > 0; h--, dst_line += pitch )
  166. +    {
  167. +   int x;
  168. +
  169. +   for ( x = 0; x < width; x++ )
  170. +   {
  171. +       unsigned char* src;
  172. +
  173. +#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
  174. +
  175. +            /* compute target pixel location in source space */
  176. +       vector.x = (x            * 0x10000) + 0x10000 / 2;
  177. +       vector.y = ((height - h) * 0x10000) + 0x10000 / 2;
  178. +       FT_Vector_Transform(&vector, &inverse);
  179. +       vector.x = CLAMP(FT_RoundFix(vector.x) / 0x10000, 0, source->width - 1);
  180. +       vector.y = CLAMP(FT_RoundFix(vector.y) / 0x10000, 0, source->rows  - 1);
  181. +
  182. +       switch ( source->pixel_mode )
  183. +       {
  184. +       case FT_PIXEL_MODE_MONO: /* convert mono to 8-bit gray, scale using nearest pixel */
  185. +       src = src_buf + (vector.y * src_pitch);
  186. +       if ( src[(vector.x >> 3)] & (0x80 >> (vector.x & 7)) )
  187. +           dst_line[x] = 0xff;
  188. +       break;
  189. +
  190. +       case FT_PIXEL_MODE_GRAY: /* scale using nearest pixel */
  191. +       src = src_buf + (vector.y * src_pitch);
  192. +       dst_line[x] = src[vector.x];
  193. +       break;
  194. +
  195. +       case FT_PIXEL_MODE_BGRA: /* scale by averaging all relevant source pixels, keep BGRA format */
  196. +       {
  197. +       int sample_x, sample_y;
  198. +       int bgra[4] = {};
  199. +       for (sample_y = - sampling_height; sample_y < sampling_height + 1; ++sample_y)
  200. +       {
  201. +           int src_y = CLAMP(vector.y + sample_y, 0, source->rows - 1);
  202. +           src = src_buf + (src_y * src_pitch);
  203. +           for (sample_x = - sampling_width; sample_x < sampling_width + 1; ++sample_x)
  204. +           {
  205. +           int src_x = CLAMP(vector.x + sample_x, 0, source->width - 1);
  206. +           for (int i = 0; i < 4; ++i)
  207. +               bgra[i] += src[src_x * 4 + i];
  208. +           }
  209. +       }
  210. +
  211. +       for (int i = 0; i < 4; ++i)
  212. +           dst_line[4 * x + i] = bgra[i] / sample_count;
  213. +       break;
  214. +       }
  215. +       }
  216. +   }
  217. +    }
  218. +}
  219. +
  220. +/* this functions converts the glyph bitmap found in a FT_GlyphSlot
  221.   * into a different format (see _compute_xrender_bitmap_size)
  222.   *
  223.   * you should call this function after _compute_xrender_bitmap_size
  224. @@ -244,6 +363,11 @@ _fill_xrender_bitmap( FT_Bitmap*   target,
  225.         }
  226.         break;
  227.  
  228. +   case FT_PIXEL_MODE_BGRA: /* Preserve BGRA format */
  229. +       for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
  230. +       memcpy( dstLine, srcLine, width * 4 );
  231. +       break;
  232. +
  233.     case FT_PIXEL_MODE_LCD:
  234.         if ( !bgr )
  235.         {
  236. @@ -365,6 +489,8 @@ XftFontLoadGlyphs (Display      *dpy,
  237.      FT_Vector      vector;
  238.      FT_Face        face;
  239.      FT_Render_Mode  mode = FT_RENDER_MODE_MONO;
  240. +    FcBool     transform;
  241. +    FcBool     glyph_transform;
  242.  
  243.      if (!info)
  244.     return;
  245. @@ -374,6 +500,8 @@ XftFontLoadGlyphs (Display      *dpy,
  246.      if (!face)
  247.     return;
  248.  
  249. +    if (font->info.color)
  250. +        mode = FT_RENDER_MODE_NORMAL;
  251.      if (font->info.antialias)
  252.      {
  253.     switch (font->info.rgba) {
  254. @@ -390,6 +518,8 @@ XftFontLoadGlyphs (Display      *dpy,
  255.     }
  256.      }
  257.  
  258. +    transform = font->info.transform && mode != FT_RENDER_MODE_MONO;
  259. +
  260.      while (nglyph--)
  261.      {
  262.     glyphindex = *glyphs++;
  263. @@ -440,7 +570,7 @@ XftFontLoadGlyphs (Display      *dpy,
  264.     /*
  265.      * Compute glyph metrics from FreeType information
  266.      */
  267. -   if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
  268. +   if (transform)
  269.     {
  270.         /*
  271.          * calculate the true width by transforming all four corners.
  272. @@ -487,7 +617,7 @@ XftFontLoadGlyphs (Display      *dpy,
  273.      * Clip charcell glyphs to the bounding box
  274.      * XXX transformed?
  275.      */
  276. -   if (font->info.spacing >= FC_CHARCELL && !font->info.transform)
  277. +   if (font->info.spacing >= FC_CHARCELL && !transform)
  278.     {
  279.         if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
  280.         {
  281. @@ -519,18 +649,20 @@ XftFontLoadGlyphs (Display        *dpy,
  282.         }
  283.     }
  284.  
  285. +   glyph_transform = transform;
  286.     if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
  287.     {
  288.         error = FT_Render_Glyph( face->glyph, mode );
  289.         if (error)
  290.         continue;
  291. +       glyph_transform = False;
  292.     }
  293.  
  294.     FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
  295.  
  296.     if (font->info.spacing >= FC_MONO)
  297.     {
  298. -       if (font->info.transform)
  299. +       if (transform)
  300.         {
  301.         if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
  302.         {
  303. @@ -613,14 +745,27 @@ XftFontLoadGlyphs (Display        *dpy,
  304.         }
  305.     }
  306.  
  307. -   size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
  308. +   size = _compute_xrender_bitmap_size( &local, glyphslot, mode, glyph_transform ? &font->info.matrix : NULL );
  309.     if ( size < 0 )
  310.         continue;
  311.  
  312.     xftg->metrics.width  = local.width;
  313.     xftg->metrics.height = local.rows;
  314. -   xftg->metrics.x      = - glyphslot->bitmap_left;
  315. -   xftg->metrics.y      =   glyphslot->bitmap_top;
  316. +   if (transform)
  317. +   {
  318. +       vector.x = - glyphslot->bitmap_left;
  319. +       vector.y =   glyphslot->bitmap_top;
  320. +
  321. +       FT_Vector_Transform(&vector, &font->info.matrix);
  322. +
  323. +       xftg->metrics.x = (short)vector.x;
  324. +       xftg->metrics.y = (short)vector.y;
  325. +   }
  326. +   else
  327. +   {
  328. +       xftg->metrics.x = (short)(- glyphslot->bitmap_left);
  329. +       xftg->metrics.y = (short)(  glyphslot->bitmap_top);
  330. +   }
  331.  
  332.     /*
  333.      * If the glyph is relatively large (> 1% of server memory),
  334. @@ -645,9 +790,12 @@ XftFontLoadGlyphs (Display     *dpy,
  335.  
  336.     local.buffer = bufBitmap;
  337.  
  338. -   _fill_xrender_bitmap( &local, glyphslot, mode,
  339. -                 (font->info.rgba == FC_RGBA_BGR ||
  340. -                  font->info.rgba == FC_RGBA_VBGR ) );
  341. +        if (mode == FT_RENDER_MODE_NORMAL && glyph_transform)
  342. +            _scaled_fill_xrender_bitmap(&local, &glyphslot->bitmap, &font->info.matrix);
  343. +        else
  344. +       _fill_xrender_bitmap( &local, glyphslot, mode,
  345. +                     (font->info.rgba == FC_RGBA_BGR ||
  346. +                      font->info.rgba == FC_RGBA_VBGR ) );
  347.  
  348.     /*
  349.      * Copy or convert into local buffer.
  350. @@ -662,6 +810,7 @@ XftFontLoadGlyphs (Display      *dpy,
  351.      */
  352.     glyph = (Glyph) glyphindex;
  353.  
  354. +   xftg->picture = 0;
  355.     xftg->glyph_memory = size + sizeof (XftGlyph);
  356.     if (font->format)
  357.     {
  358. @@ -685,15 +834,35 @@ XftFontLoadGlyphs (Display        *dpy,
  359.             }
  360.         }
  361.         }
  362. -       else if ( mode != FT_RENDER_MODE_NORMAL )
  363. +       else if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA || mode != FT_RENDER_MODE_NORMAL)
  364.         {
  365.         /* invert ARGB <=> BGRA */
  366.         if (ImageByteOrder (dpy) != XftNativeByteOrder ())
  367.             XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
  368.         }
  369. -       XRenderAddGlyphs (dpy, font->glyphset, &glyph,
  370. -                 &xftg->metrics, 1,
  371. -                 (char *) bufBitmap, size);
  372. +
  373. +       if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
  374. +       {
  375. +       Pixmap pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), local.width, local.rows, 32);
  376. +       GC gc = XCreateGC(dpy, pixmap, 0, NULL);
  377. +       XImage image = {
  378. +           local.width, local.rows, 0, ZPixmap, (char *)bufBitmap,
  379. +           dpy->byte_order, dpy->bitmap_unit, dpy->bitmap_bit_order, 32,
  380. +           32, local.width * 4 - local.pitch, 32,
  381. +           0, 0, 0
  382. +       };
  383. +
  384. +       XInitImage(&image);
  385. +       XPutImage(dpy, pixmap, gc, &image, 0, 0, 0, 0, local.width, local.rows);
  386. +       xftg->picture = XRenderCreatePicture(dpy, pixmap, font->format, 0, NULL);
  387. +
  388. +       XFreeGC(dpy, gc);
  389. +       XFreePixmap(dpy, pixmap);
  390. +       }
  391. +       else
  392. +       XRenderAddGlyphs (dpy, font->glyphset, &glyph,
  393. +                 &xftg->metrics, 1,
  394. +                 (char *) bufBitmap, size);
  395.     }
  396.     else
  397.     {
  398. @@ -744,7 +913,9 @@ XftFontUnloadGlyphs (Display        *dpy,
  399.     {
  400.         if (font->format)
  401.         {
  402. -       if (font->glyphset)
  403. +       if (xftg->picture)
  404. +           XRenderFreePicture(dpy, xftg->picture);
  405. +       else if (font->glyphset)
  406.         {
  407.             glyphBuf[nused++] = (Glyph) glyphindex;
  408.             if (nused == sizeof (glyphBuf) / sizeof (glyphBuf[0]))
  409. diff -up ../../xft-2.3.3/src/xftint.h ./xftint.h
  410. --- ../../xft-2.3.3/src/xftint.h    2019-03-16 19:12:27.000000000 +0100
  411. +++ ./xftint.h  2020-05-12 23:14:56.192927924 +0200
  412. @@ -85,6 +85,7 @@ typedef struct _XftGlyph {
  413.      XGlyphInfo     metrics;
  414.      void       *bitmap;
  415.      unsigned long   glyph_memory;
  416. +    Picture         picture;
  417.  } XftGlyph;
  418.  
  419.  /*
  420. @@ -134,6 +135,7 @@ struct _XftFontInfo {
  421.      FT_F26Dot6     xsize, ysize;   /* pixel size */
  422.      FcBool     antialias;  /* doing antialiasing */
  423.      FcBool     embolden;   /* force emboldening */
  424. +    FcBool     color;      /* contains color glyphs */
  425.      int            rgba;       /* subpixel order */
  426.      int            lcd_filter; /* lcd filter */
  427.      FT_Matrix      matrix;     /* glyph transformation matrix */
  428. diff -up ../../xft-2.3.3/src/xftrender.c ./xftrender.c
  429. --- ../../xft-2.3.3/src/xftrender.c 2019-03-16 19:12:27.000000000 +0100
  430. +++ ./xftrender.c   2020-05-12 23:24:27.014745637 +0200
  431. @@ -26,6 +26,35 @@
  432.  #define NUM_ELT_LOCAL  128
  433.  
  434.  /*
  435. + * Dispatch glyph drawing to the correct XRenderCompositeString function
  436. + */
  437. +static void
  438. +_XftCompositeString (Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat* format, GlyphSet glyphset, int srcx, int srcy, int dstx, int dsty, int charwidth, unsigned int* chars, int nchars)
  439. +{
  440. +    if (nchars == 0)
  441. +        return;
  442. +
  443. +    switch (charwidth) {
  444. +    case 1:
  445. +    default:
  446. +   XRenderCompositeString8 (dpy, op,
  447. +                src, dst, format, glyphset,
  448. +                srcx, srcy, dstx, dsty, (char*)chars, nchars);
  449. +   break;
  450. +    case 2:
  451. +   XRenderCompositeString16(dpy, op,
  452. +                src, dst, format, glyphset,
  453. +                srcx, srcy, dstx, dsty, (unsigned short*)chars, nchars);
  454. +   break;
  455. +    case 4:
  456. +   XRenderCompositeString32(dpy, op,
  457. +                src, dst, format, glyphset,
  458. +                srcx, srcy, dstx, dsty, (unsigned int*)chars, nchars);
  459. +   break;
  460. +    }
  461. +}
  462. +
  463. +/*
  464.   * Use the Render extension to draw the glyphs
  465.   */
  466.  
  467. @@ -43,12 +72,14 @@ XftGlyphRender (Display     *dpy,
  468.         int     nglyphs)
  469.  {
  470.      XftFontInt     *font = (XftFontInt *) pub;
  471. -    int            i;
  472. +    int            i, j;
  473.      FT_UInt        missing[XFT_NMISSING];
  474.      int            nmissing;
  475.      FT_UInt        g, max;
  476.      int            size, width;
  477. +    int            dstx, dsty;
  478.      Glyph      wire;
  479. +    XftGlyph*       glyph;
  480.      char       *char8;
  481.      unsigned short  *char16;
  482.      unsigned int    *char32;
  483. @@ -100,43 +131,75 @@ XftGlyphRender (Display       *dpy,
  484.     if (!chars)
  485.         goto bail1;
  486.      }
  487. +    dstx = x;
  488. +    dsty = y;
  489.      char8 = (char *) chars;
  490.      char16 = (unsigned short *) chars;
  491.      char32 = (unsigned int *) chars;
  492. -    for (i = 0; i < nglyphs; i++)
  493. +    for (i = 0, j = 0; i < nglyphs; i++)
  494.      {
  495.     wire = (Glyph) glyphs[i];
  496.     if (wire >= font->num_glyphs || !font->glyphs[wire])
  497.         wire = 0;
  498. -   switch (width) {
  499. -   case 1: char8[i] = (char) wire; break;
  500. -   case 2: char16[i] = (unsigned short) wire; break;
  501. -   case 4: char32[i] = (unsigned long) wire; break;
  502. +        glyph = font->glyphs[wire];
  503. +   if (glyph->picture)
  504. +   {
  505. +       _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
  506. +       XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, dstx, dsty - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
  507. +       x = dstx = dstx + glyph->metrics.xOff;
  508. +       x = dsty = dsty + glyph->metrics.yOff;
  509. +       j = 0;
  510. +   }
  511. +   else
  512. +   {
  513. +       switch (width) {
  514. +       case 1: char8[j] = (char) wire; break;
  515. +       case 2: char16[j] = (unsigned short) wire; break;
  516. +       case 4: char32[j] = (unsigned int) wire; break;
  517. +       }
  518. +       dstx += glyph->metrics.xOff;
  519. +       dsty += glyph->metrics.yOff;
  520. +       ++j;
  521.     }
  522.      }
  523. -    switch (width) {
  524. +    _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
  525. +    if (chars != char_local)
  526. +   free (chars);
  527. +bail1:
  528. +    if (glyphs_loaded)
  529. +   _XftFontManageMemory (dpy, pub);
  530. +}
  531. +
  532. +/*
  533. + * Dispatch glyph drawing to the correct XRenderCompositeText function
  534. + */
  535. +static void
  536. +_XftCompositeText (Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat* format, int srcx, int srcy, int dstx, int dsty, int eltwidth, XGlyphElt8* elts, int nelt)
  537. +{
  538. +    if (nelt == 0)
  539. +        return;
  540. +
  541. +    switch (eltwidth) {
  542.      case 1:
  543.      default:
  544. -   XRenderCompositeString8 (dpy, op,
  545. -                src, dst, font->format, font->glyphset,
  546. -                srcx, srcy, x, y, char8, nglyphs);
  547. +   XRenderCompositeText8 (dpy, op,
  548. +                  src, dst, format,
  549. +                  srcx, srcy, dstx, dsty,
  550. +                          (XGlyphElt8*)elts, nelt);
  551.     break;
  552.      case 2:
  553. -   XRenderCompositeString16(dpy, op,
  554. -                src, dst, font->format, font->glyphset,
  555. -                srcx, srcy, x, y, char16, nglyphs);
  556. +   XRenderCompositeText16(dpy, op,
  557. +                  src, dst, format,
  558. +                  srcx, srcy, dstx, dsty,
  559. +                          (XGlyphElt16*)elts, nelt);
  560.     break;
  561.      case 4:
  562. -   XRenderCompositeString32(dpy, op,
  563. -                src, dst, font->format, font->glyphset,
  564. -                srcx, srcy, x, y, char32, nglyphs);
  565. +   XRenderCompositeText32(dpy, op,
  566. +                  src, dst, format,
  567. +                  srcx, srcy, dstx, dsty,
  568. +                          (XGlyphElt32*)elts, nelt);
  569.     break;
  570.      }
  571. -    if (chars != char_local)
  572. -   free (chars);
  573. -bail1:
  574. -    if (glyphs_loaded)
  575. -   _XftFontManageMemory (dpy, pub);
  576.  }
  577.  
  578.  _X_EXPORT void
  579. @@ -251,9 +314,10 @@ XftGlyphSpecRender (Display            *dpy,
  580.         g = 0;
  581.     /*
  582.      * check to see if the glyph is placed where it would
  583. -    * fall using the normal spacing
  584. +    * fall using the normal spacing and if it would render
  585. +    * as a XRender glyph
  586.      */
  587. -   if ((glyph = font->glyphs[g]))
  588. +   if ((glyph = font->glyphs[g]) && !glyph->picture)
  589.     {
  590.         if (x != glyphs[i].x || y != glyphs[i].y)
  591.         {
  592. @@ -267,7 +331,7 @@ XftGlyphSpecRender (Display         *dpy,
  593.      }
  594.  
  595.      elts = elts_local;
  596. -    if (nelt > NUM_ELT_LOCAL)
  597. +    if (!font->info.color && nelt > NUM_ELT_LOCAL)
  598.      {
  599.     elts = malloc (nelt * sizeof (XGlyphElt8));
  600.     if (!elts)
  601. @@ -275,7 +339,7 @@ XftGlyphSpecRender (Display         *dpy,
  602.      }
  603.  
  604.      /*
  605. -     * Generate the list of glyph elts
  606. +     * Generate the list of glyph elts or render color glyphs
  607.       */
  608.      nelt = 0;
  609.      x = y = 0;
  610. @@ -289,6 +353,11 @@ XftGlyphSpecRender (Display            *dpy,
  611.         g = 0;
  612.     if ((glyph = font->glyphs[g]))
  613.     {
  614. +       if (glyph->picture)
  615. +       {
  616. +                XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, glyphs[i].x, glyphs[i].y - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
  617. +                continue;
  618. +       }
  619.         if (!i || x != glyphs[i].x || y != glyphs[i].y)
  620.         {
  621.         if (n)
  622. @@ -320,23 +389,9 @@ XftGlyphSpecRender (Display            *dpy,
  623.     elts[nelt].nchars = n;
  624.     nelt++;
  625.      }
  626. -    switch (width) {
  627. -    case 1:
  628. -   XRenderCompositeText8 (dpy, op, src, dst, font->format,
  629. -                  srcx, srcy, glyphs[0].x, glyphs[0].y,
  630. -                  elts, nelt);
  631. -   break;
  632. -    case 2:
  633. -   XRenderCompositeText16 (dpy, op, src, dst, font->format,
  634. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  635. -               (XGlyphElt16 *) elts, nelt);
  636. -   break;
  637. -    case 4:
  638. -   XRenderCompositeText32 (dpy, op, src, dst, font->format,
  639. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  640. -               (XGlyphElt32 *) elts, nelt);
  641. -   break;
  642. -    }
  643. +    _XftCompositeText(dpy, op, src, dst, font->format,
  644. +             srcx, srcy, glyphs[0].x, glyphs[0].y,
  645. +             width, elts, nelt);
  646.  
  647.      if (elts != elts_local)
  648.     free (elts);
  649. @@ -535,7 +590,7 @@ XftGlyphFontSpecRender (Display             *d
  650.      * check to see if the glyph is placed where it would
  651.      * fall using the normal spacing
  652.      */
  653. -   if ((glyph = font->glyphs[g]))
  654. +   if ((glyph = font->glyphs[g]) && !glyph->picture)
  655.     {
  656.         if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
  657.         {
  658. @@ -560,7 +615,7 @@ XftGlyphFontSpecRender (Display             *d
  659.      }
  660.  
  661.      /*
  662. -     * Generate the list of glyph elts
  663. +     * Generate the list of glyph elts and render color glyphs
  664.       */
  665.      nelt = 0;
  666.      x = y = 0;
  667. @@ -578,6 +633,11 @@ XftGlyphFontSpecRender (Display                *d
  668.         g = 0;
  669.     if ((glyph = font->glyphs[g]))
  670.     {
  671. +       if (glyph->picture)
  672. +       {
  673. +                XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, glyphs[i].x, glyphs[i].y - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
  674. +                continue;
  675. +       }
  676.         if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
  677.         {
  678.         if (n)
  679. @@ -610,23 +670,9 @@ XftGlyphFontSpecRender (Display                *d
  680.     elts[nelt].nchars = n;
  681.     nelt++;
  682.      }
  683. -    switch (width) {
  684. -    case 1:
  685. -   XRenderCompositeText8 (dpy, op, src, dst, format,
  686. -                  srcx, srcy, glyphs[0].x, glyphs[0].y,
  687. -                  elts, nelt);
  688. -   break;
  689. -    case 2:
  690. -   XRenderCompositeText16 (dpy, op, src, dst, format,
  691. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  692. -               (XGlyphElt16 *) elts, nelt);
  693. -   break;
  694. -    case 4:
  695. -   XRenderCompositeText32 (dpy, op, src, dst, format,
  696. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  697. -               (XGlyphElt32 *) elts, nelt);
  698. -   break;
  699. -    }
  700. +    _XftCompositeText(dpy, op, src, dst, format,
  701. +             srcx, srcy, glyphs[0].x, glyphs[0].y,
  702. +             width, elts, nelt);
  703.  
  704.      if (elts != elts_local)
  705.     free (elts);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement