logo
Литература_1 / photon_old

Написание текста в прямоугольной области

Написание текста в прямоугольнике заданного размера может оказаться непростым делом, если неизвестен размер строки. Рассмотрим прямоугольник фиксированных размеров, например, ячейку электронной таблицы. Как вы определите, сколько символов можно успешно отобразить в этой ячейке без отсечения? Вызовите функцию PfExtentTextToRect(). Передайте ей отсекающий прямоугольник, идентификатор шрифта, строку, максимальное число байтов в строке, и она сообщит Вам число символов и занимаемое ими пространство, которые уменьшаются внутри отсекающего прямоугольника. Это полезно для размещения многоточий (...) после обрезанной строки и недопущения частично обрезанных символов. В настоящее время эта функция поддерживает отсечение только по горизонтальной оси.

Вот пример:

/* PfExtentTextToRect */

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <Ap.h>

#include <Ph.h>

#include <Pt.h>

#include <errno.h>

PtWidget_t * pwndMain = NULL, * pbtn = NULL, * pobjRaw = NULL;

char * pcText = "pAfaBfbfffffffffffffffCfcXfxYfyZfzf";

char * pcGB = "\323\316\317\267";

char ** ppcData = NULL;

int fnDrawCanvas( PtWidget_t * ptsWidget, PhTile_t * ptsDamage );

#define FALSE 0

FontName szFont;

char * pmbGB = NULL;

struct PxTransCtrl * ptsTrans = NULL;

int iTemp1 = 0, iTemp2 = 0;

#define BUFFER_SIZE 256

int main (int argc, char *argv[]) {

PtArg_t args[4];

PhPoint_t win_size, pntPOS, pntDIM;

short nArgs = 0;

if ((pmbGB = calloc(BUFFER_SIZE, sizeof(char))) = = NULL) return(EXIT_FAILURE);

PtInit (NULL);

if (argc > 1) {

if(PfGenerateFontName(argv[1], 0, 9, szFont) = = NULL)

PfGenerateFontName("TextFont", 0, 9, szFont);

}

else PfGenerateFontName("TextFont", 0, 9, szFont);

if ((ptsTrans = PxTranslateSet(NULL, "GB2312-80")) = = NULL) return(EXIT_FAILURE);

if (PxTranslateToUTF(ptsTrans, pcGB, 4, &iTemp1, pmbGB, BUFFER_SIZE, &iTemp2) = = -1)

printf("Не получается перевести из GB в UTF.\n");

if(argc > 2) pcText = pmbGB;

/* Установка базовых параметров pwndMain */

win_size.x = 450;

win_size.y = 450;

PtSetArg(&args[0],Pt_ARG_DIM, &win_size, 0);

PtSetArg(&args[1],Pt_ARG_WINDOW_TITLE, "PfExtentTextToRect", 0);

pwndMain = PtCreateWidget (PtWindow, Pt_NO_PARENT, 2, args);

nArgs = 0;

pntPOS.x = 100;

pntPOS.y = 10;

PtSetArg(&args[nArgs], Pt_ARG_POS, &pntPOS, 0);

nArgs++;

PtSetArg(&args[nArgs], Pt_ARG_TEXT_STRING, pcText, NULL);

nArgs++;

PtSetArg(&args[nArgs], Pt_ARG_TEXT_FONT, szFont, NULL);

nArgs++;

pbtn = PtCreateWidget(PtButton, pwndMain, nArgs, args);

PtRealizeWidget(pbtn);

pntPOS.y = 100;

pntPOS.x = 75;

pntDIM.x = 300;

pntDIM.y = 300;

PtSetArg(&args[0], Pt_ARG_POS, &pntPOS, 0);

PtSetArg(&args[1], Pt_ARG_DIM, &pntDIM, 0);

PtSetArg(&args[2], Pt_ARG_RAW_DRAW_F, fnDrawCanvas, 0L);

pobjRaw = PtCreateWidget(PtRaw, pwndMain, 3, args);

PtRealizeWidget(pwndMain);

PtMainLoop ();

return(0);

} // main()

#define ASCENDER tsExtent.ul.y

#define DESCENDER tsExtent.lr.y

int fnDrawCanvas( PtWidget_t * ptsWidget, PhTile_t * ptsDamage ) {

PhRect_t tsExtentClip;

PhRect_t rect;

PhPoint_t pnt;

PhRect_t tsExtent;

PgColor_t old;

PhPoint_t pnt2;

PhPoint_t tsPos = {0, 0};

int iRet = 0;

int iBytes = 0;

/* Находим наш холст */

PtBasicWidgetCanvas(pobjRaw, &rect);

old = PgSetStrokeColor(Pg_BLACK);

PfExtentText(&tsExtent, &tsPos, szFont, pcText, strlen(pcText));

/* Рисуем текст */

pnt.x = 10 + rect.ul.x;

pnt.y = 100 + rect.ul.y;

PgSetFont(szFont);

PgSetTextColor(Pg_BLACK);

PgDrawText(pcText, strlen(pcText), &pnt, 0);

pnt.x -= 10;

pnt2.x = pnt.x + tsExtent.lr.x + 20;

pnt2.y = pnt.y;

PgSetStrokeColor(Pg_BLUE);

PgDrawLine(&pnt, &pnt2);

pnt.x = 10 + rect.ul.x;

pnt.y = 100 + rect.ul.y;

PgSetStrokeColor(Pg_RED);

PgDrawIRect(tsExtent.ul.x + pnt.x, tsExtent.ul.y + pnt.y,

(tsExtent.lr.x - min(tsExtent.ul.x, 0) + 1) + pnt.x,

tsExtent.lr.y + pnt.y,

Pg_DRAW_STROKE);

if ((iRet = PfExtentTextToRect(&tsExtentClip, szFont, &tsExtent, pcText, strlen(pcText))) = = -1)

printf("PfExtentTextToRect неудача 1.\n");

else {

printf("lrx = = %d, %d символов в строке.\n", tsExtent.lr.x, utf8strlen(pcText, &iBytes));

printf("PfExtentTextToRect lrx = = %d, %d символов разместятся в обрезке %d.\n",

tsExtentClip.lr.x, iRet, tsExtent.lr.x);

}

tsExtent.lr.x /= 2;

if ((iRet = PfExtentTextToRect(&tsExtentClip, szFont, &tsExtent, pcText, strlen(pcText))) = = -1)

printf("PfExtentTextToRect неудача 2.\n");

else {

printf("lrx == %d, %d символов в строке.\n", tsExtent.lr.x, utf8strlen(pcText, &iBytes));

printf("PfExtentTextToRect lrx == %d, %d символов разместятся в обрезке %d.\n",

tsExtentClip.lr.x, iRet, tsExtent.lr.x);

}

pnt.x = 10 + rect.ul.x;

pnt.y = 150 + rect.ul.y;

PgDrawText(pcText, iRet, &pnt, 0);

PgDrawIRect(tsExtentClip.ul.x + pnt.x,

tsExtentClip.ul.y + pnt.y,

(tsExtentClip.lr.x - min(tsExtentClip.ul.x, 0) + 1) + pnt.x,

tsExtentClip.lr.y + pnt.y,

Pg_DRAW_STROKE);

tsExtent.lr.x /= 2;

if ((iRet = PfExtentTextToRect(&tsExtentClip, szFont, &tsExtent, pcText, strlen(pcText))) = = -1)

printf("PfExtentTextToRect неудача 3.\n");

else {

printf("lrx == %d, %d символов в строке.\n", tsExtent.lr.x, utf8strlen(pcText, &iBytes));

printf("PfExtentTextToRect lrx == %d, %d символов разместятся в обрезке %d.\n",

tsExtentClip.lr.x, iRet, tsExtent.lr.x);

}

pnt.x = 10 + rect.ul.x;

pnt.y = 200 + rect.ul.y;

PgDrawText(pcText, iRet, &pnt, 0);

PgDrawIRect(tsExtentClip.ul.x + pnt.x, tsExtentClip.ul.y + pnt.y,

(tsExtentClip.lr.x - min(tsExtentClip.ul.x, 0) + 1) + pnt.x,

tsExtentClip.lr.y + pnt.y,

Pg_DRAW_STROKE);

PgSetStrokeColor(old);

return( Pt_CONTINUE );

}

Yandex.RTB R-A-252273-3
Yandex.RTB R-A-252273-4