Guest User

bgra patch for libXft

a guest
Apr 28th, 2022
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 21.04 KB | None | 0 0
  1. diff --git a/src/xftfreetype.c b/src/xftfreetype.c
  2. index 1f79a81..18230a8 100644
  3. --- a/src/xftfreetype.c
  4. +++ b/src/xftfreetype.c
  5. @@ -523,7 +523,7 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
  6.      /*
  7.       * Compute glyph load flags
  8.       */
  9. -    fi->load_flags = FT_LOAD_DEFAULT;
  10. +    fi->load_flags = FT_LOAD_DEFAULT | FT_LOAD_COLOR;
  11.  
  12.  #ifndef XFT_EMBEDDED_BITMAP
  13.  #define XFT_EMBEDDED_BITMAP "embeddedbitmap"
  14. @@ -775,6 +775,7 @@ XftFontOpenInfo (Display    *dpy,
  15.      FcChar32       hash_value;
  16.      FcChar32       rehash_value;
  17.      FcBool     antialias;
  18. +    FcBool     color;
  19.      int            max_glyph_memory;
  20.      int            alloc_size;
  21.      int            ascent, descent, height;
  22. @@ -831,12 +832,16 @@ XftFontOpenInfo (Display  *dpy,
  23.      if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
  24.     antialias = FcFalse;
  25.  
  26. +    color = FT_HAS_COLOR(face) ? FcTrue : FcFalse;
  27. +
  28.      /*
  29.       * Find the appropriate picture format
  30.       */
  31.      if (fi->render)
  32.      {
  33. -   if (antialias)
  34. +   if (color)
  35. +       format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
  36. +   else if (antialias)
  37.     {
  38.         switch (fi->rgba) {
  39.         case FC_RGBA_RGB:
  40. @@ -851,9 +856,7 @@ XftFontOpenInfo (Display    *dpy,
  41.         }
  42.     }
  43.     else
  44. -   {
  45.         format = XRenderFindStandardFormat (dpy, PictStandardA1);
  46. -   }
  47.  
  48.     if (!format)
  49.         goto bail2;
  50. @@ -968,6 +971,13 @@ XftFontOpenInfo (Display   *dpy,
  51.       * which doesn't happen in XftFontInfoFill
  52.      */
  53.     font->info.antialias = antialias;
  54. +
  55. +    /*
  56. +     * Set color value, which is only known once the
  57. +     * font was loaded
  58. +     */
  59. +    font->info.color = color;
  60. +
  61.     /*
  62.      * bump XftFile reference count
  63.      */
  64. diff --git a/src/xftglyphs.c b/src/xftglyphs.c
  65. index b536df4..2fc45d4 100644
  66. --- a/src/xftglyphs.c
  67. +++ b/src/xftglyphs.c
  68. @@ -26,6 +26,8 @@
  69.  
  70. #include FT_SYNTHESIS_H
  71.  
  72. +#include FT_GLYPH_H
  73. +
  74. /*
  75.  * Validate the memory info for a font
  76.  */
  77. @@ -78,9 +80,11 @@ _XftFontValidateMemory (Display *dpy, XftFont *public)
  78. static int
  79.  _compute_xrender_bitmap_size( FT_Bitmap*   target,
  80.                   FT_GlyphSlot  slot,
  81. -                 FT_Render_Mode    mode )
  82. +                 FT_Render_Mode    mode,
  83. +                 FT_Matrix*        matrix )
  84. {
  85.      FT_Bitmap* ftbit;
  86. +    FT_Vector  vector;
  87.      int        width, height, pitch;
  88.  
  89.     if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
  90. @@ -91,6 +95,16 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
  91.  
  92.     width = (int)ftbit->width;
  93.     height = (int)ftbit->rows;
  94. +
  95. +    if ( matrix && mode == FT_RENDER_MODE_NORMAL )
  96. +    {
  97. +   vector.x = ftbit->width;
  98. +   vector.y = ftbit->rows;
  99. +   FT_Vector_Transform(&vector, matrix);
  100. +
  101. +   width = (int)vector.x;
  102. +   height = (int)vector.y;
  103. +    }
  104.     pitch = (width+3) & ~3;
  105.  
  106.     switch ( ftbit->pixel_mode )
  107. @@ -112,6 +126,10 @@ _compute_xrender_bitmap_size( FT_Bitmap*   target,
  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. @@ -142,6 +160,105 @@ _compute_xrender_bitmap_size( FT_Bitmap*  target,
  119.     return pitch * height;
  120. }
  121.  
  122. +/* this functions converts the glyph bitmap found in a FT_GlyphSlot
  123. + * into a different format while scaling by applying the given matrix
  124. + * (see _compute_xrender_bitmap_size)
  125. + *
  126. + * you should call this function after _compute_xrender_bitmap_size
  127. + *
  128. + * target :: target bitmap descriptor. Note that its 'buffer' pointer
  129. + *           must point to memory allocated by the caller
  130. + *
  131. + * source :: the source bitmap descriptor
  132. + *
  133. + * matrix :: the scaling matrix to apply
  134. + */
  135. +static void
  136. +_scaled_fill_xrender_bitmap( FT_Bitmap*    target,
  137. +                    FT_Bitmap* source,
  138. +                             const FT_Matrix* matrix )
  139. +{
  140. +    unsigned char* src_buf   = source->buffer;
  141. +    unsigned char* dst_line  = target->buffer;
  142. +    int            src_pitch = source->pitch;
  143. +    int            width     = target->width;
  144. +    int            height    = target->rows;
  145. +    int            pitch     = target->pitch;
  146. +    int            h;
  147. +    FT_Vector      vector;
  148. +    FT_Matrix      inverse   = *matrix;
  149. +    int            sampling_width;
  150. +    int            sampling_height;
  151. +    int            sample_count;
  152. +
  153. +    if ( src_pitch < 0 )
  154. +   src_buf -= src_pitch*(source->rows-1);
  155. +
  156. +    FT_Matrix_Invert(&inverse);
  157. +
  158. +    /* compute how many source pixels a target pixel spans */
  159. +    vector.x = 1;
  160. +    vector.y = 1;
  161. +    FT_Vector_Transform(&vector, &inverse);
  162. +    sampling_width = vector.x / 2;
  163. +    sampling_height = vector.y / 2;
  164. +    sample_count = (2 * sampling_width + 1) * (2 * sampling_height + 1);
  165. +
  166. +    for    ( h = height; h > 0; h--, dst_line += pitch )
  167. +    {
  168. +   int x;
  169. +
  170. +   for ( x = 0; x < width; x++ )
  171. +   {
  172. +       unsigned char* src;
  173. +
  174. +#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
  175. +
  176. +            /* compute target pixel location in source space */
  177. +       vector.x = (x            * 0x10000) + 0x10000 / 2;
  178. +       vector.y = ((height - h) * 0x10000) + 0x10000 / 2;
  179. +       FT_Vector_Transform(&vector, &inverse);
  180. +       vector.x = CLAMP(FT_RoundFix(vector.x) / 0x10000, 0, source->width - 1);
  181. +       vector.y = CLAMP(FT_RoundFix(vector.y) / 0x10000, 0, source->rows  - 1);
  182. +
  183. +       switch ( source->pixel_mode )
  184. +       {
  185. +       case FT_PIXEL_MODE_MONO: /* convert mono to 8-bit gray, scale using nearest pixel */
  186. +       src = src_buf + (vector.y * src_pitch);
  187. +       if ( src[(vector.x >> 3)] & (0x80 >> (vector.x & 7)) )
  188. +           dst_line[x] = 0xff;
  189. +       break;
  190. +
  191. +       case FT_PIXEL_MODE_GRAY: /* scale using nearest pixel */
  192. +       src = src_buf + (vector.y * src_pitch);
  193. +       dst_line[x] = src[vector.x];
  194. +       break;
  195. +
  196. +       case FT_PIXEL_MODE_BGRA: /* scale by averaging all relevant source pixels, keep BGRA format */
  197. +       {
  198. +       int sample_x, sample_y;
  199. +       int bgra[4] = {};
  200. +       for (sample_y = - sampling_height; sample_y < sampling_height + 1; ++sample_y)
  201. +       {
  202. +           int src_y = CLAMP(vector.y + sample_y, 0, source->rows - 1);
  203. +           src = src_buf + (src_y * src_pitch);
  204. +           for (sample_x = - sampling_width; sample_x < sampling_width + 1; ++sample_x)
  205. +           {
  206. +           int src_x = CLAMP(vector.x + sample_x, 0, source->width - 1);
  207. +           for (int i = 0; i < 4; ++i)
  208. +               bgra[i] += src[src_x * 4 + i];
  209. +           }
  210. +       }
  211. +
  212. +       for (int i = 0; i < 4; ++i)
  213. +           dst_line[4 * x + i] = bgra[i] / sample_count;
  214. +       break;
  215. +       }
  216. +       }
  217. +   }
  218. +    }
  219. +}
  220. +
  221. /* this functions converts the glyph bitmap found in a FT_GlyphSlot
  222.  * into a different format (see _compute_xrender_bitmap_size)
  223.  *
  224. @@ -244,6 +361,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 +487,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 +498,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 +516,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 +568,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 +615,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 +647,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 +743,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  = (unsigned short)local.width;
  313.     xftg->metrics.height = (unsigned short)local.rows;
  314. -   xftg->metrics.x      = (short)(- glyphslot->bitmap_left);
  315. -   xftg->metrics.y      = (short)(  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 +788,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 +808,7 @@ XftFontLoadGlyphs (Display      *dpy,
  351.      */
  352.     glyph = (Glyph) glyphindex;
  353.  
  354. +   xftg->picture = 0;
  355.     xftg->glyph_memory = (size_t)size + sizeof (XftGlyph);
  356.     if (font->format)
  357.     {
  358. @@ -685,15 +832,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 +911,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 --git a/src/xftint.h b/src/xftint.h
  410. index ced9a02..1af40fe 100644
  411. --- a/src/xftint.h
  412. +++ b/src/xftint.h
  413. @@ -85,6 +85,7 @@ typedef struct _XftGlyph {
  414.      XGlyphInfo     metrics;
  415.      void       *bitmap;
  416.     unsigned long   glyph_memory;
  417. +    Picture         picture;
  418. } XftGlyph;
  419.  
  420. /*
  421. @@ -134,6 +135,7 @@ struct _XftFontInfo {
  422.      FT_F26Dot6     xsize, ysize;   /* pixel size */
  423.      FcBool     antialias;  /* doing antialiasing */
  424.      FcBool     embolden;   /* force emboldening */
  425. +    FcBool     color;      /* contains color glyphs */
  426.      int            rgba;       /* subpixel order */
  427.      int            lcd_filter; /* lcd filter */
  428.      FT_Matrix      matrix;     /* glyph transformation matrix */
  429. diff --git a/src/xftrender.c b/src/xftrender.c
  430. index a352737..7937e98 100644
  431. --- a/src/xftrender.c
  432. +++ b/src/xftrender.c
  433. @@ -25,6 +25,35 @@
  434.  #define NUM_LOCAL  1024
  435.  #define NUM_ELT_LOCAL  128
  436.  
  437. +/*
  438. + * Dispatch glyph drawing to the correct XRenderCompositeString function
  439. + */
  440. +static void
  441. +_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)
  442. +{
  443. +    if (nchars == 0)
  444. +        return;
  445. +
  446. +    switch (charwidth) {
  447. +    case 1:
  448. +    default:
  449. +   XRenderCompositeString8 (dpy, op,
  450. +                src, dst, format, glyphset,
  451. +                srcx, srcy, dstx, dsty, (char*)chars, nchars);
  452. +   break;
  453. +    case 2:
  454. +   XRenderCompositeString16(dpy, op,
  455. +                src, dst, format, glyphset,
  456. +                srcx, srcy, dstx, dsty, (unsigned short*)chars, nchars);
  457. +   break;
  458. +    case 4:
  459. +   XRenderCompositeString32(dpy, op,
  460. +                src, dst, format, glyphset,
  461. +                srcx, srcy, dstx, dsty, (unsigned int*)chars, nchars);
  462. +   break;
  463. +    }
  464. +}
  465. +
  466. /*
  467.  * Use the Render extension to draw the glyphs
  468.  */
  469. @@ -43,12 +72,14 @@ XftGlyphRender (Display     *dpy,
  470.         int     nglyphs)
  471. {
  472.      XftFontInt     *font = (XftFontInt *) pub;
  473. -    int            i;
  474. +    int            i, j;
  475.      FT_UInt        missing[XFT_NMISSING];
  476.      int            nmissing;
  477.      FT_UInt        g, max;
  478.      int            size, width;
  479. +    int            dstx, dsty;
  480.      Glyph      wire;
  481. +    XftGlyph*       glyph;
  482.      char       *char8;
  483.     unsigned short  *char16;
  484.     unsigned int    *char32;
  485. @@ -100,43 +131,75 @@ XftGlyphRender (Display       *dpy,
  486.     if (!chars)
  487.         goto bail1;
  488.     }
  489. +    dstx = x;
  490. +    dsty = y;
  491.     char8 = (char *) chars;
  492.     char16 = (unsigned short *) chars;
  493.     char32 = (unsigned int *) chars;
  494. -    for (i = 0; i < nglyphs; i++)
  495. +    for (i = 0, j = 0; i < nglyphs; i++)
  496.     {
  497.     wire = (Glyph) glyphs[i];
  498.     if (wire >= font->num_glyphs || !font->glyphs[wire])
  499.         wire = 0;
  500. -   switch (width) {
  501. -   case 1: char8[i] = (char) wire; break;
  502. -   case 2: char16[i] = (unsigned short) wire; break;
  503. -   case 4: char32[i] = (unsigned int) wire; break;
  504. +        glyph = font->glyphs[wire];
  505. +   if (glyph->picture)
  506. +   {
  507. +       _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
  508. +       XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, dstx, dsty - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
  509. +       x = dstx = dstx + glyph->metrics.xOff;
  510. +       x = dsty = dsty + glyph->metrics.yOff;
  511. +       j = 0;
  512. +   }
  513. +   else
  514. +   {
  515. +       switch (width) {
  516. +       case 1: char8[j] = (char) wire; break;
  517. +       case 2: char16[j] = (unsigned short) wire; break;
  518. +       case 4: char32[j] = (unsigned int) wire; break;
  519. +       }
  520. +       dstx += glyph->metrics.xOff;
  521. +       dsty += glyph->metrics.yOff;
  522. +       ++j;
  523.     }
  524.     }
  525. -    switch (width) {
  526. +    _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
  527. +    if (chars != char_local)
  528. +   free (chars);
  529. +bail1:
  530. +    if (glyphs_loaded)
  531. +   _XftFontManageMemory (dpy, pub);
  532. +}
  533. +
  534. +/*
  535. + * Dispatch glyph drawing to the correct XRenderCompositeText function
  536. + */
  537. +static void
  538. +_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)
  539. +{
  540. +    if (nelt == 0)
  541. +        return;
  542. +
  543. +    switch (eltwidth) {
  544.     case 1:
  545.     default:
  546. -   XRenderCompositeString8 (dpy, op,
  547. -                src, dst, font->format, font->glyphset,
  548. -                srcx, srcy, x, y, char8, nglyphs);
  549. +   XRenderCompositeText8 (dpy, op,
  550. +                  src, dst, format,
  551. +                  srcx, srcy, dstx, dsty,
  552. +                          (XGlyphElt8*)elts, nelt);
  553.     break;
  554.     case 2:
  555. -   XRenderCompositeString16(dpy, op,
  556. -                src, dst, font->format, font->glyphset,
  557. -                srcx, srcy, x, y, char16, nglyphs);
  558. +   XRenderCompositeText16(dpy, op,
  559. +                  src, dst, format,
  560. +                  srcx, srcy, dstx, dsty,
  561. +                          (XGlyphElt16*)elts, nelt);
  562.     break;
  563.     case 4:
  564. -   XRenderCompositeString32(dpy, op,
  565. -                src, dst, font->format, font->glyphset,
  566. -                srcx, srcy, x, y, char32, nglyphs);
  567. +   XRenderCompositeText32(dpy, op,
  568. +                  src, dst, format,
  569. +                  srcx, srcy, dstx, dsty,
  570. +                          (XGlyphElt32*)elts, nelt);
  571.     break;
  572.     }
  573. -    if (chars != char_local)
  574. -   free (chars);
  575. -bail1:
  576. -    if (glyphs_loaded)
  577. -   _XftFontManageMemory (dpy, pub);
  578. }
  579.  
  580. _X_EXPORT void
  581. @@ -251,9 +314,10 @@ XftGlyphSpecRender (Display            *dpy,
  582.         g = 0;
  583.     /*
  584.      * check to see if the glyph is placed where it would
  585. -    * fall using the normal spacing
  586. +    * fall using the normal spacing and if it would render
  587. +    * as a XRender glyph
  588.      */
  589. -   if ((glyph = font->glyphs[g]))
  590. +   if ((glyph = font->glyphs[g]) && !glyph->picture)
  591.     {
  592.         if (x != glyphs[i].x || y != glyphs[i].y)
  593.         {
  594. @@ -267,7 +331,7 @@ XftGlyphSpecRender (Display         *dpy,
  595.     }
  596.  
  597.     elts = elts_local;
  598. -    if (nelt > NUM_ELT_LOCAL)
  599. +    if (!font->info.color && nelt > NUM_ELT_LOCAL)
  600.     {
  601.     elts = malloc ((size_t)nelt * sizeof (XGlyphElt8));
  602.     if (!elts)
  603. @@ -275,7 +339,7 @@ XftGlyphSpecRender (Display         *dpy,
  604.     }
  605.  
  606.     /*
  607. -     * Generate the list of glyph elts
  608. +     * Generate the list of glyph elts or render color glyphs
  609.      */
  610.     nelt = 0;
  611.     x = y = 0;
  612. @@ -289,6 +353,11 @@ XftGlyphSpecRender (Display            *dpy,
  613.         g = 0;
  614.     if ((glyph = font->glyphs[g]))
  615.     {
  616. +       if (glyph->picture)
  617. +       {
  618. +                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);
  619. +                continue;
  620. +       }
  621.         if (!i || x != glyphs[i].x || y != glyphs[i].y)
  622.         {
  623.         if (n)
  624. @@ -320,23 +389,9 @@ XftGlyphSpecRender (Display            *dpy,
  625.     elts[nelt].nchars = n;
  626.     nelt++;
  627.     }
  628. -    switch (width) {
  629. -    case 1:
  630. -   XRenderCompositeText8 (dpy, op, src, dst, font->format,
  631. -                  srcx, srcy, glyphs[0].x, glyphs[0].y,
  632. -                  elts, nelt);
  633. -   break;
  634. -    case 2:
  635. -   XRenderCompositeText16 (dpy, op, src, dst, font->format,
  636. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  637. -               (XGlyphElt16 *) elts, nelt);
  638. -   break;
  639. -    case 4:
  640. -   XRenderCompositeText32 (dpy, op, src, dst, font->format,
  641. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  642. -               (XGlyphElt32 *) elts, nelt);
  643. -   break;
  644. -    }
  645. +    _XftCompositeText(dpy, op, src, dst, font->format,
  646. +             srcx, srcy, glyphs[0].x, glyphs[0].y,
  647. +             width, elts, nelt);
  648.  
  649.     if (elts != elts_local)
  650.     free (elts);
  651. @@ -535,7 +590,7 @@ XftGlyphFontSpecRender (Display             *dpy,
  652.      * check to see if the glyph is placed where it would
  653.      * fall using the normal spacing
  654.      */
  655. -   if ((glyph = font->glyphs[g]))
  656. +   if ((glyph = font->glyphs[g]) && !glyph->picture)
  657.     {
  658.         if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
  659.         {
  660. @@ -560,7 +615,7 @@ XftGlyphFontSpecRender (Display             *dpy,
  661.     }
  662.  
  663.     /*
  664. -     * Generate the list of glyph elts
  665. +     * Generate the list of glyph elts and render color glyphs
  666.      */
  667.     nelt = 0;
  668.     x = y = 0;
  669. @@ -578,6 +633,11 @@ XftGlyphFontSpecRender (Display                *dpy,
  670.         g = 0;
  671.     if ((glyph = font->glyphs[g]))
  672.     {
  673. +       if (glyph->picture)
  674. +       {
  675. +                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);
  676. +                continue;
  677. +       }
  678.         if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
  679.         {
  680.         if (n)
  681. @@ -610,23 +670,9 @@ XftGlyphFontSpecRender (Display                *dpy,
  682.     elts[nelt].nchars = n;
  683.     nelt++;
  684.     }
  685. -    switch (width) {
  686. -    case 1:
  687. -   XRenderCompositeText8 (dpy, op, src, dst, format,
  688. -                  srcx, srcy, glyphs[0].x, glyphs[0].y,
  689. -                  elts, nelt);
  690. -   break;
  691. -    case 2:
  692. -   XRenderCompositeText16 (dpy, op, src, dst, format,
  693. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  694. -               (XGlyphElt16 *) elts, nelt);
  695. -   break;
  696. -    case 4:
  697. -   XRenderCompositeText32 (dpy, op, src, dst, format,
  698. -               srcx, srcy, glyphs[0].x, glyphs[0].y,
  699. -               (XGlyphElt32 *) elts, nelt);
  700. -   break;
  701. -    }
  702. +    _XftCompositeText(dpy, op, src, dst, format,
  703. +             srcx, srcy, glyphs[0].x, glyphs[0].y,
  704. +             width, elts, nelt);
  705.  
  706.     if (elts != elts_local)
  707.     free (elts);
  708.  
Advertisement
Add Comment
Please, Sign In to add comment