home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / extensions / lib / PEXlib / pl_font.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  15.4 KB  |  646 lines

  1. /* $XConsortium: pl_font.c,v 1.7 92/11/23 16:58:54 mor Exp $ */
  2.  
  3. /******************************************************************************
  4. Copyright 1987,1991 by Digital Equipment Corporation, Maynard, Massachusetts
  5. Copyright 1992 by the Massachusetts Institute of Technology
  6.  
  7.                         All Rights Reserved
  8.  
  9. Permission to use, copy, modify, distribute, and sell this software and its
  10. documentation for any purpose is hereby granted without fee, provided that
  11. the above copyright notice appear in all copies and that both that copyright
  12. notice and this permission notice appear in supporting documentation, and that
  13. the name of Digital or M.I.T. not be used in advertising or publicity
  14. pertaining to distribution of the software without specific, written prior
  15. permission.  Digital and M.I.T. make no representations about the suitability
  16. of this software for any purpose.  It is provided "as is" without express or
  17. implied warranty.
  18.  
  19. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  20. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  21. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  22. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  23. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  24. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  25. SOFTWARE.
  26. ******************************************************************************/
  27.  
  28. #include "PEXlib.h"
  29. #include "PEXlibint.h"
  30.  
  31.  
  32. PEXFont
  33. PEXLoadFont (display, fontname)
  34.  
  35. INPUT Display    *display;
  36. INPUT char    *fontname;
  37.  
  38. {
  39.     pexLoadFontReq    *req;
  40.     pexFont        id;
  41.  
  42.  
  43.     /*
  44.      * Lock around critical section, for multithreading.
  45.      */
  46.  
  47.     LockDisplay (display);
  48.  
  49.  
  50.     /*
  51.      * Put the request in the X request buffer.
  52.      */
  53.  
  54.     PEXGetReq (LoadFont, req);
  55.     req->numBytes = strlen (fontname);
  56.     req->font = id = XAllocID (display);
  57.     req->length += (req->numBytes + 3) >> 2;
  58.  
  59.     Data (display, (char *) fontname, req->numBytes);
  60.  
  61.  
  62.     /*
  63.      * Done, so unlock and check for synchronous-ness.
  64.      */
  65.  
  66.     UnlockDisplay (display);
  67.     PEXSyncHandle (display);
  68.  
  69.     return (id);
  70. }
  71.  
  72.  
  73. void
  74. PEXUnloadFont (display, font)
  75.  
  76. INPUT Display    *display;
  77. INPUT PEXFont    font;
  78.  
  79. {
  80.     pexResourceReq *req;
  81.  
  82.  
  83.     /*
  84.      * Lock around the critical section, for multithreading.
  85.      */
  86.  
  87.     LockDisplay (display);
  88.  
  89.  
  90.     /*
  91.      * Put the request in the X request buffer.
  92.      */
  93.  
  94.     PEXGetReq (UnloadFont, req);
  95.     req->id = font;
  96.  
  97.  
  98.     /*
  99.      * Done, so unlock and check for synchronous-ness.
  100.      */
  101.  
  102.     UnlockDisplay (display);
  103.     PEXSyncHandle (display);
  104. }
  105.  
  106.  
  107. PEXFontInfo *
  108. PEXQueryFont (display, font)
  109.  
  110. INPUT Display        *display;
  111. INPUT PEXFont        font;
  112.  
  113. {
  114.     pexQueryFontReply     rep;
  115.     pexQueryFontReq    *req;
  116.     pexFontInfo        *buf;
  117.     int         prop_size;
  118.     PEXFontInfo        *fontInfoReturn;
  119.  
  120.  
  121.     /*
  122.      * Lock around critical section, for multithreading.
  123.      */
  124.  
  125.     LockDisplay (display);
  126.  
  127.  
  128.     /*
  129.      * Put the request in the X request buffer and get a reply.
  130.      */
  131.  
  132.     PEXGetReq (QueryFont, req);
  133.     req->font = font;
  134.  
  135.     if (_XReply (display, &rep, 0, xFalse) == 0)
  136.     {
  137.     UnlockDisplay (display);
  138.     PEXSyncHandle (display);
  139.     return (NULL);            /* return an error */
  140.     }
  141.  
  142.  
  143.     /*
  144.      * Allocate a scratch buffer and copy the reply data to the buffer.
  145.      */
  146.  
  147.     buf = (pexFontInfo *) _XAllocScratch (display,
  148.     (unsigned long) (rep.length << 2));
  149.  
  150.     _XRead (display, (char *) buf, (long) (rep.length << 2));
  151.  
  152.  
  153.     /*
  154.      * Allocate a buffer for the replies to pass back to the client.
  155.      */
  156.  
  157.     fontInfoReturn = (PEXFontInfo *)
  158.     PEXAllocBuf ((unsigned) sizeof (PEXFontInfo));
  159.  
  160.     fontInfoReturn->first_glyph = buf->firstGlyph;
  161.     fontInfoReturn->last_glyph = buf->lastGlyph;
  162.     fontInfoReturn->default_glyph = buf->defaultGlyph;
  163.     fontInfoReturn->all_exist = buf->allExist;
  164.     fontInfoReturn->stroke = buf->strokeFont;
  165.     fontInfoReturn->count = buf->numProps;
  166.  
  167.     prop_size = buf->numProps * sizeof (PEXFontProp);
  168.     fontInfoReturn->props = (PEXFontProp *) PEXAllocBuf ((unsigned ) prop_size);
  169.     buf++;
  170.     COPY_AREA ((char *) buf, (char *) fontInfoReturn->props, prop_size);
  171.  
  172.  
  173.     /*
  174.      * Done, so unlock and check for synchronous-ness.
  175.      */
  176.  
  177.     UnlockDisplay (display);
  178.     PEXSyncHandle (display);
  179.  
  180.     return (fontInfoReturn);
  181. }
  182.  
  183.  
  184. char **
  185. PEXListFonts (display, pattern, maxNames, countReturn)
  186.  
  187. INPUT Display        *display;
  188. INPUT char        *pattern;
  189. INPUT unsigned int    maxNames;
  190. OUTPUT unsigned long    *countReturn;
  191.  
  192. {
  193.     pexListFontsReply     rep;
  194.     pexListFontsReq       *req;
  195.     long        numChars;
  196.     pexString         *repStrings;
  197.     char        **names;
  198.     int            i;
  199.  
  200.  
  201.     /*
  202.      * Lock around critical section, for multithreading.
  203.      */
  204.  
  205.     LockDisplay (display);
  206.  
  207.  
  208.     /*
  209.      * Put the request in the X request buffer and get a reply.
  210.      */
  211.  
  212.     PEXGetReq (ListFonts, req);
  213.     req->maxNames = maxNames;
  214.     numChars = req->numChars = strlen (pattern);
  215.     req->length += (numChars + 3) >> 2;
  216.  
  217.     Data (display, (char *) pattern, numChars);
  218.  
  219.     if (_XReply (display, &rep, 0, xFalse) == 0)
  220.     {
  221.     UnlockDisplay (display);
  222.     PEXSyncHandle (display);
  223.     *countReturn = 0;
  224.     return (NULL);            /* return an error */
  225.     }
  226.  
  227.     *countReturn = rep.numStrings;
  228.  
  229.  
  230.     /*
  231.      * Allocate a scratch buffer and copy the reply data to the buffer.
  232.      */
  233.  
  234.     repStrings = (pexString *)
  235.     _XAllocScratch (display, (unsigned long) (rep.length << 2));
  236.  
  237.     _XRead (display, (char *) repStrings, (long) (rep.length << 2));
  238.  
  239.  
  240.     /*
  241.      * Allocate a buffer for the replies to pass back to the client.
  242.      */
  243.  
  244.     names = (char **) PEXAllocBuf (rep.numStrings * sizeof (char *));
  245.  
  246.     for (i = 0; i < rep.numStrings; i++)
  247.     {
  248.     names[i] = (char *) PEXAllocBuf ((unsigned) repStrings->length + 1);
  249.  
  250.     COPY_AREA ((char *) &repStrings[1], names[i],
  251.         (unsigned) repStrings->length);
  252.     names[i][repStrings->length] = '\0';    /* null terminate string */
  253.  
  254.     repStrings = (pexString *) ((char *) repStrings +
  255.         PADDED_BYTES (sizeof (pexString) + repStrings->length));
  256.     }
  257.  
  258.  
  259.     /*
  260.      * Done, so unlock and check for synchronous-ness.
  261.      */
  262.  
  263.     UnlockDisplay (display);
  264.     PEXSyncHandle (display);
  265.  
  266.     return (names);
  267. }
  268.  
  269.  
  270. char **
  271. PEXListFontsWithInfo (display, pattern, maxNames, countReturn, fontInfoReturn)
  272.  
  273. INPUT Display        *display;
  274. INPUT char        *pattern;
  275. INPUT unsigned int    maxNames;
  276. OUTPUT unsigned long    *countReturn;
  277. OUTPUT PEXFontInfo    **fontInfoReturn;
  278.  
  279. {
  280.     pexListFontsWithInfoReq    *req;
  281.     pexListFontsWithInfoReply    rep;
  282.     long            numChars;
  283.     int                font_info_size, prop_size;
  284.     int                numFontInfoReturn, i;
  285.     char            *buf, **names;
  286.     pexString            *repStrings;
  287.     PEXFontInfo            *pFontInfo;
  288.  
  289.  
  290.     /*
  291.      * Lock around critical section, for multithreading.
  292.      */
  293.  
  294.     LockDisplay (display);
  295.  
  296.  
  297.     /*
  298.      * Put the request in the X request buffer and get a reply.
  299.      */
  300.  
  301.     PEXGetReq (ListFontsWithInfo, req);
  302.     req->maxNames = maxNames;
  303.     numChars = req->numChars = strlen (pattern);
  304.     req->length += (numChars + 3) >> 2;
  305.  
  306.     Data (display, (char *) pattern, numChars);
  307.  
  308.     if (_XReply (display, &rep, 0, xFalse) == 0)
  309.     {
  310.     UnlockDisplay (display);
  311.         PEXSyncHandle (display);
  312.     *countReturn = 0;
  313.         return (NULL);                /* return an error */
  314.     }
  315.  
  316.     *countReturn = rep.numStrings;
  317.  
  318.  
  319.     /*
  320.      * Allocate a scratch buffer and copy the reply data to the buffer.
  321.      */
  322.  
  323.     buf = (char *) _XAllocScratch (display, (unsigned long) (rep.length << 2));
  324.  
  325.     _XRead (display, (char *) buf, (long) (rep.length << 2));
  326.  
  327.  
  328.     /*
  329.      * Allocate a buffer for the font names to pass back to the client.
  330.      */
  331.  
  332.     names = (char **) PEXAllocBuf (rep.numStrings * sizeof (char *));
  333.  
  334.     repStrings = (pexString *) buf;
  335.     for (i = 0; i < rep.numStrings; i++)
  336.     {
  337.         names[i] = (char *) PEXAllocBuf ((unsigned) repStrings->length + 1);
  338.  
  339.         COPY_AREA ((char *) &repStrings[1], names[i],
  340.             (unsigned) repStrings->length);
  341.     names[i][repStrings->length] = '\0';    /* null terminate string */
  342.  
  343.         repStrings = (pexString *) ((char *) repStrings +
  344.             PADDED_BYTES (sizeof (pexString) + repStrings->length));
  345.     }
  346.  
  347.  
  348.     /*
  349.      * Allocate a buffer for the font info to pass back to the client.
  350.      */
  351.  
  352.     buf = (char *) repStrings;
  353.     numFontInfoReturn = (int) *((CARD32 *) buf); 
  354.     buf += sizeof (CARD32);
  355.  
  356.     font_info_size = numFontInfoReturn * sizeof (PEXFontInfo);
  357.     *fontInfoReturn = pFontInfo = (PEXFontInfo *) PEXAllocBuf (font_info_size);
  358.  
  359.     for (i = 0; i < numFontInfoReturn; i++, pFontInfo++)
  360.     {
  361.     pFontInfo->first_glyph = ((pexFontInfo *) buf)->firstGlyph;
  362.     pFontInfo->last_glyph = ((pexFontInfo *) buf)->lastGlyph;
  363.     pFontInfo->default_glyph = ((pexFontInfo *) buf)->defaultGlyph;
  364.     pFontInfo->all_exist = ((pexFontInfo *) buf)->allExist;
  365.     pFontInfo->stroke = ((pexFontInfo *) buf)->strokeFont;
  366.     pFontInfo->count = ((pexFontInfo *) buf)->numProps;
  367.  
  368.     prop_size = ((pexFontInfo *) buf)->numProps * sizeof (PEXFontProp);
  369.     pFontInfo->props = (PEXFontProp *) PEXAllocBuf ((unsigned ) prop_size);
  370.     buf += sizeof (pexFontInfo);
  371.         COPY_AREA ((char *) buf, (char *) pFontInfo->props, prop_size);
  372.     buf += prop_size;
  373.     }
  374.  
  375.  
  376.     /*
  377.      * Done, so unlock and check for synchronous-ness.
  378.      */
  379.  
  380.     UnlockDisplay (display);
  381.     PEXSyncHandle (display);
  382.  
  383.     return (names);
  384. }
  385.  
  386.  
  387. PEXTextExtent *
  388. PEXQueryTextExtents (display, id, fontGroup, path, expansion, spacing, height, 
  389.     halign, valign, count, text)
  390.  
  391. INPUT Display            *display;
  392. INPUT XID            id;
  393. INPUT unsigned int        fontGroup;
  394. INPUT int            path;
  395. INPUT double            expansion;
  396. INPUT double            spacing;
  397. INPUT double            height;
  398. INPUT int            halign;
  399. INPUT int            valign;
  400. INPUT unsigned long        count;
  401. INPUT PEXStringData        *text;
  402. {
  403.     pexQueryTextExtentsReq    *req;
  404.     pexQueryTextExtentsReply     rep;
  405.     char            *ch;
  406.     pexMonoEncoding         pMonoEncoding;
  407.     int                convertFP, numEncodings, i;
  408.     PEXTextExtent        *textExtent, *ptextExtents;
  409.  
  410.  
  411.     /*
  412.      * Lock around critical section, for multithreading.
  413.      */
  414.  
  415.     LockDisplay (display);
  416.  
  417.  
  418.     /*
  419.      * Put the request in the X request buffer and get a reply.
  420.      */
  421.  
  422.     PEXGetFPReq (QueryTextExtents, req, convertFP);
  423.     req->textPath = path;
  424.     req->id = id;
  425.     req->fontGroupIndex = (pexTableIndex) fontGroup;
  426.     req->charExpansion = expansion;
  427.     req->charSpacing = spacing;
  428.     req->charHeight = height;
  429.     req->textAlignment.vertical = valign;
  430.     req->textAlignment.horizontal = halign;
  431.     req->numStrings = count;
  432.  
  433.     req->length += count * (LENOF (CARD32) + LENOF (pexMonoEncoding));
  434.     for (i = 0; i < count; i++)
  435.     req->length += (((int) text[i].length + 3) >> 2);
  436.  
  437.     pMonoEncoding.characterSet = (INT16) 1;
  438.     pMonoEncoding.characterSetWidth = (CARD8) PEXCSByte;
  439.     pMonoEncoding.encodingState = 0;  
  440.  
  441.     numEncodings = 1;
  442.  
  443.     for (i = 0; i < count; i++)
  444.     {
  445.     Data (display, (char *) &numEncodings, sizeof (CARD32));
  446.     pMonoEncoding.numChars = (CARD16) (text[i].length);
  447.     Data (display, (char *) &pMonoEncoding, sizeof (pexMonoEncoding));
  448.     Data (display, (char *) text[i].ch, text[i].length);
  449.     }
  450.  
  451.     if (_XReply (display, &rep, 0, xFalse) == 0)
  452.     {
  453.         UnlockDisplay (display);
  454.         PEXSyncHandle (display);
  455.         return (NULL);            /* return an error */
  456.     }
  457.  
  458.  
  459.     /*
  460.      * Allocate a scratch buffer and copy the reply data to the buffer.
  461.      */
  462.  
  463.     ch = (char *) _XAllocScratch (display, (unsigned long) (rep.length << 2));
  464.  
  465.     _XRead (display, ch, (long) (rep.length << 2));
  466.  
  467.  
  468.     /*
  469.      * Allocate a buffer for the replies to pass back to the client.
  470.      */
  471.  
  472.     textExtent = ptextExtents =
  473.     (PEXTextExtent *) PEXAllocBuf (count * sizeof (PEXTextExtent));
  474.  
  475.     for (i = 0; i < count; i++, textExtent++)
  476.     {
  477.     textExtent->lower_left = *(PEXCoord2D *) ch;
  478.     ch += sizeof (PEXCoord2D);
  479.     textExtent->upper_right = *(PEXCoord2D *) ch;
  480.     ch += sizeof (PEXCoord2D);
  481.     textExtent->concat_point = *(PEXCoord2D *) ch;
  482.     ch += sizeof (PEXCoord2D);
  483.     }
  484.  
  485.  
  486.     /*
  487.      * Done, so unlock and check for synchronous-ness.
  488.      */
  489.  
  490.     UnlockDisplay (display);
  491.     PEXSyncHandle (display);
  492.  
  493.     return (ptextExtents);
  494. }
  495.  
  496.  
  497. PEXTextExtent *
  498. PEXQueryEncodedTextExtents (display, id, fontGroup, path, expansion,
  499.     spacing, height, halign, valign, count, encoded_text)
  500.  
  501. INPUT Display            *display;
  502. INPUT XID            id;
  503. INPUT unsigned int        fontGroup;
  504. INPUT int            path;
  505. INPUT double            expansion;
  506. INPUT double            spacing;
  507. INPUT double            height;
  508. INPUT int            halign;
  509. INPUT int            valign;
  510. INPUT unsigned long        count;
  511. INPUT PEXListOfEncodedText        *encoded_text;
  512.  
  513. {
  514.     pexQueryTextExtentsReq    *req;
  515.     pexQueryTextExtentsReply     rep;
  516.     PEXEncodedTextData          *string;
  517.     char            *ch;
  518.     int                i, j;
  519.     int                convertFP;
  520.     PEXTextExtent        *textExtent, *ptextExtents;
  521.  
  522.  
  523.     /*
  524.      * Lock around critical section, for multithreading.
  525.      */
  526.  
  527.     LockDisplay (display);
  528.  
  529.  
  530.     /*
  531.      * Put the request in the X request buffer.
  532.      */
  533.  
  534.     PEXGetFPReq (QueryTextExtents, req, convertFP);
  535.     req->textPath = path;
  536.     req->id = id;
  537.     req->fontGroupIndex = (pexTableIndex) fontGroup;
  538.     req->charExpansion = expansion;
  539.     req->charSpacing = spacing;
  540.     req->charHeight = height;
  541.     req->textAlignment.vertical = valign;
  542.     req->textAlignment.horizontal = halign;
  543.     req->numStrings = count;
  544.  
  545.  
  546.     /*
  547.      * Update the request length header.
  548.      */
  549.  
  550.     req->length += (count * LENOF (CARD32));
  551.     for (i = 0; i < count; i++)
  552.     {
  553.     string = encoded_text[i].encoded_text;
  554.     for (j = 0; j < (int) encoded_text[i].count; j++, string++)
  555.     {
  556.         req->length += LENOF (pexMonoEncoding);
  557.         if (string->character_set_width == PEXCSLong) 
  558.         req->length += string->length;
  559.         else if (string->character_set_width == PEXCSShort) 
  560.         req->length += ((int) string->length + 1) >> 1;
  561.         else /* string->character_set_width == PEXCSByte) */ 
  562.         req->length += ((int) string->length + 3) >> 2;
  563.     } 
  564.     }
  565.  
  566.  
  567.     /*
  568.      * Put the encoded text in the request.
  569.      */
  570.  
  571.     for (i = 0; i < count; i++)
  572.     {
  573.     unsigned long numEncodings = encoded_text[i].count;
  574.     string = encoded_text[i].encoded_text;
  575.  
  576.     Data (display, (char *) &numEncodings, sizeof (CARD32));
  577.  
  578.     for (j = 0; j < (int) numEncodings; j++, string++)
  579.     {
  580.         Data (display, (char *) string, sizeof (pexMonoEncoding));
  581.  
  582.         if (string->character_set_width == PEXCSLong) 
  583.         {
  584.         Data (display, string->ch, string->length * sizeof (long));
  585.         }
  586.         else if (string->character_set_width == PEXCSShort) 
  587.         {
  588.         Data (display, string->ch, string->length * sizeof (short));
  589.         }
  590.         else /* string->character_set_width == PEXCSByte) */ 
  591.         {
  592.         Data (display, string->ch, string->length);
  593.         }
  594.     }
  595.     }
  596.  
  597.  
  598.     /*
  599.      * Get a reply.
  600.      */
  601.  
  602.     if (_XReply (display, &rep, 0, xFalse) == 0)
  603.     {
  604.         UnlockDisplay (display);
  605.         PEXSyncHandle (display);
  606.         return (NULL);            /* return an error */
  607.     }
  608.  
  609.  
  610.     /*
  611.      * Allocate a scratch buffer and copy the reply data to the buffer.
  612.      */
  613.  
  614.     ch = (char *) _XAllocScratch (display, (unsigned long) (rep.length << 2));
  615.  
  616.     _XRead (display, ch, (long) (rep.length << 2));
  617.  
  618.  
  619.     /*
  620.      * Allocate a buffer for the replies to pass back to the client.
  621.      */
  622.  
  623.     textExtent = ptextExtents =
  624.     (PEXTextExtent *) PEXAllocBuf (count * sizeof (PEXTextExtent));
  625.  
  626.     for (i = 0; i < count; i++, textExtent++)
  627.     {
  628.     textExtent->lower_left = *(PEXCoord2D *) ch;
  629.     ch += sizeof (PEXCoord2D);
  630.     textExtent->upper_right = *(PEXCoord2D *) ch;
  631.     ch += sizeof (PEXCoord2D);
  632.     textExtent->concat_point = *(PEXCoord2D *) ch;
  633.     ch += sizeof (PEXCoord2D);
  634.     }
  635.  
  636.  
  637.     /*
  638.      * Done, so unlock and check for synchronous-ness.
  639.      */
  640.  
  641.     UnlockDisplay (display);
  642.     PEXSyncHandle (display);
  643.  
  644.     return (ptextExtents);
  645. }
  646.