123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- #include "sys-defines.h"
- #include "extern.h"
- #define GOOD_PRINTABLE_ASCII(c) ((c >= 0x20) && (c <= 0x7E))
- /* CGM horizontal alignment styles, indexed by internal number
- (left/center/right) */
- static const int cgm_horizontal_alignment_style[PL_NUM_HORIZ_JUST_TYPES] =
- { CGM_ALIGN_LEFT, CGM_ALIGN_CENTER, CGM_ALIGN_RIGHT };
- /* corresponding strings, as used in the text encoding */
- static const char * const cgm_horizontal_alignment_style_string[PL_NUM_HORIZ_JUST_TYPES] =
- { "left", "ctr", "right" };
- /* CGM vertical alignment styles, indexed by internal number
- (top/half/base/bottom/cap) */
- static const int cgm_vertical_alignment_style[PL_NUM_VERT_JUST_TYPES] =
- { CGM_ALIGN_TOP, CGM_ALIGN_HALF, CGM_ALIGN_BASE, CGM_ALIGN_BOTTOM, CGM_ALIGN_CAP };
- /* corresponding strings, as used in the text encoding */
- static const char * const cgm_vertical_alignment_style_string[PL_NUM_VERT_JUST_TYPES] =
- { "top", "half", "base", "bottom", "cap" };
- /* This prints a single-font, single-font-size label. */
- double
- _pl_c_paint_text_string (R___(Plotter *_plotter) const unsigned char *s, int h_just, int v_just)
- {
- int master_font_index, desired_cgm_font_id;
- double theta, costheta, sintheta;
- double user_text_transformation_matrix[6];
- double text_transformation_matrix[6];
- int desired_char_base_vector_x, desired_char_base_vector_y;
- int desired_char_up_vector_x, desired_char_up_vector_y;
- double relative_cap_height, user_cap_height;
- double up_vector_x, up_vector_y, cap_height;
- double base_vector_x, base_vector_y, base_width;
- int desired_char_height, desired_base_width;
- bool font_is_symbol, need_lower_half, need_upper_half;
- bool set_lower_half_charset = false, set_upper_half_charset = false;
- int lower_half_charset = 0, upper_half_charset = 0; /* dummy values */
- const unsigned char *t;
- double width;
- int desired_cgm_h_alignment, desired_cgm_v_alignment;
- int byte_count, data_byte_count, data_len;
- /* sanity check */
- if (_plotter->drawstate->font_type != PL_F_POSTSCRIPT)
- return 0.0;
-
- if (*s == (unsigned char)'\0')
- return 0.0;
-
- if (_plotter->drawstate->true_font_size == 0.0)
- return 0.0;
-
- _pl_c_set_pen_color (R___(_plotter) CGM_OBJECT_TEXT);
-
- master_font_index =
- (_pl_g_ps_typeface_info[_plotter->drawstate->typeface_index].fonts)[_plotter->drawstate->font_index];
-
- _plotter->data->page->ps_font_used[master_font_index] = true;
-
- desired_cgm_font_id = _pl_g_ps_font_to_cgm_font_id[master_font_index];
- if (_plotter->cgm_font_id != desired_cgm_font_id)
-
- {
- data_len = 2;
- byte_count = data_byte_count = 0;
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_ATTRIBUTE_ELEMENT, 10,
- data_len, &byte_count,
- "TEXTFONTINDEX");
- _cgm_emit_index (_plotter->data->page, false, _plotter->cgm_encoding,
-
- desired_cgm_font_id + 1,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
- _plotter->cgm_font_id = desired_cgm_font_id;
- }
-
- theta = M_PI * _plotter->drawstate->text_rotation / 180.0;
- sintheta = sin (theta);
- costheta = cos (theta);
-
- user_text_transformation_matrix[0] = costheta;
- user_text_transformation_matrix[1] = sintheta;
- user_text_transformation_matrix[2] = - sintheta;
- user_text_transformation_matrix[3] = costheta;
- user_text_transformation_matrix[4] = _plotter->drawstate->pos.x;
- user_text_transformation_matrix[5] = _plotter->drawstate->pos.y;
-
- _matrix_product (user_text_transformation_matrix,
- _plotter->drawstate->transform.m,
- text_transformation_matrix);
-
- {
- double base_x = text_transformation_matrix[0];
- double base_y = text_transformation_matrix[1];
- double up_x = text_transformation_matrix[2];
- double up_y = text_transformation_matrix[3];
- double base_len = sqrt (base_x * base_x + base_y * base_y);
- double up_len = sqrt (up_x * up_x + up_y * up_y);
- double max_len = DMAX(base_len, up_len);
-
- if (max_len != 0.0)
- {
- base_x /= max_len;
- base_y /= max_len;
- up_x /= max_len;
- up_y /= max_len;
- }
- #define QUANTIZATION_FACTOR 4000
- desired_char_base_vector_x = IROUND(QUANTIZATION_FACTOR * base_x);
- desired_char_base_vector_y = IROUND(QUANTIZATION_FACTOR * base_y);
- desired_char_up_vector_x = IROUND(QUANTIZATION_FACTOR * up_x);
- desired_char_up_vector_y = IROUND(QUANTIZATION_FACTOR * up_y);
- }
-
- if (_plotter->cgm_char_base_vector_x != desired_char_base_vector_x
- || _plotter->cgm_char_base_vector_y != desired_char_base_vector_y
- || _plotter->cgm_char_up_vector_x != desired_char_up_vector_x
- || _plotter->cgm_char_up_vector_y != desired_char_up_vector_y)
-
- {
- data_len = 4 * CGM_BINARY_BYTES_PER_INTEGER;
- byte_count = data_byte_count = 0;
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_ATTRIBUTE_ELEMENT, 16,
- data_len, &byte_count,
- "CHARORI");
- _cgm_emit_integer (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_char_up_vector_x,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_integer (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_char_up_vector_y,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_integer (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_char_base_vector_x,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_integer (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_char_base_vector_y,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
-
- _plotter->cgm_char_base_vector_x = desired_char_base_vector_x;
- _plotter->cgm_char_base_vector_y = desired_char_base_vector_y;
- _plotter->cgm_char_up_vector_x = desired_char_up_vector_x;
- _plotter->cgm_char_up_vector_y = desired_char_up_vector_y;
- }
-
- relative_cap_height =
- _pl_g_ps_font_info[master_font_index].font_cap_height / 1000.0;
-
- user_cap_height = relative_cap_height * _plotter->drawstate->true_font_size;
-
- up_vector_x = user_cap_height * text_transformation_matrix[2];
- up_vector_y = user_cap_height * text_transformation_matrix[3];
-
- cap_height = sqrt (up_vector_x * up_vector_x + up_vector_y * up_vector_y);
-
- desired_char_height = IROUND(cap_height);
-
- if (_plotter->cgm_char_height != desired_char_height)
-
- {
- data_len = CGM_BINARY_BYTES_PER_INTEGER;
- byte_count = data_byte_count = 0;
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_ATTRIBUTE_ELEMENT, 15,
- data_len, &byte_count,
- "CHARHEIGHT");
- _cgm_emit_integer (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_char_height,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
- _plotter->cgm_char_height = desired_char_height;
- }
-
- if (strcmp (_pl_g_ps_font_info[master_font_index].ps_name, "Symbol") == 0)
- font_is_symbol = true;
- else
- font_is_symbol = false;
-
- need_lower_half = need_upper_half = false;
- for (t = s; *t != (unsigned char)'\0'; t++)
- {
- if ((*t) <= 127)
- need_lower_half = true;
- else
- need_upper_half = true;
- }
-
- if (font_is_symbol)
-
- {
- if (need_lower_half && _plotter->cgm_charset_lower != 3)
- {
- set_lower_half_charset = true;
- lower_half_charset = 3;
- }
- if (need_upper_half && _plotter->cgm_charset_upper != 4)
- {
- set_upper_half_charset = true;
- upper_half_charset = 4;
- }
- }
- else
-
- {
- if (need_lower_half && _plotter->cgm_charset_lower != 1)
- {
- set_lower_half_charset = true;
- lower_half_charset = 1;
- }
- if (need_upper_half && _plotter->cgm_charset_upper != 2)
- {
- set_upper_half_charset = true;
- upper_half_charset = 2;
- }
- }
- if (set_lower_half_charset)
-
- {
- data_len = 2;
- byte_count = data_byte_count = 0;
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_ATTRIBUTE_ELEMENT, 19,
- data_len, &byte_count,
- "CHARSETINDEX");
- _cgm_emit_index (_plotter->data->page, false, _plotter->cgm_encoding,
- lower_half_charset,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
- _plotter->cgm_charset_lower = lower_half_charset;
- }
- if (set_upper_half_charset)
-
- {
- data_len = 2;
- byte_count = data_byte_count = 0;
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_ATTRIBUTE_ELEMENT, 20,
- data_len, &byte_count,
- "ALTCHARSETINDEX");
- _cgm_emit_index (_plotter->data->page, false, _plotter->cgm_encoding,
- upper_half_charset,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
- _plotter->cgm_charset_upper = upper_half_charset;
- }
-
- desired_cgm_h_alignment = cgm_horizontal_alignment_style[h_just];
- desired_cgm_v_alignment = cgm_vertical_alignment_style[v_just];
- if (_plotter->cgm_horizontal_text_alignment != desired_cgm_h_alignment
- || _plotter->cgm_vertical_text_alignment != desired_cgm_v_alignment)
-
- {
- const char *desired_cgm_h_alignment_string, *desired_cgm_v_alignment_string;
- desired_cgm_h_alignment_string =
- cgm_horizontal_alignment_style_string[h_just];
- desired_cgm_v_alignment_string =
- cgm_vertical_alignment_style_string[v_just];
- data_len = 2 * 2 + 2 * 4;
- byte_count = data_byte_count = 0;
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_ATTRIBUTE_ELEMENT, 18,
- data_len, &byte_count,
- "TEXTALIGN");
- _cgm_emit_enum (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_cgm_h_alignment,
- data_len, &data_byte_count, &byte_count,
- desired_cgm_h_alignment_string);
- _cgm_emit_enum (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_cgm_v_alignment,
- data_len, &data_byte_count, &byte_count,
- desired_cgm_v_alignment_string);
- _cgm_emit_real_fixed_point (_plotter->data->page, false, _plotter->cgm_encoding,
- 0.0,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_real_fixed_point (_plotter->data->page, false, _plotter->cgm_encoding,
- 0.0,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
- _plotter->cgm_horizontal_text_alignment = desired_cgm_h_alignment;
- _plotter->cgm_vertical_text_alignment = desired_cgm_v_alignment;
- }
- if (_plotter->cgm_max_version >= 3)
-
- {
- if (_plotter->cgm_restricted_text_type
- != CGM_RESTRICTED_TEXT_TYPE_BOXED_CAP)
-
- {
- data_len = 2;
- byte_count = data_byte_count = 0;
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_ATTRIBUTE_ELEMENT, 42,
- data_len, &byte_count,
- "RESTRTEXTTYPE");
- _cgm_emit_index (_plotter->data->page, false, _plotter->cgm_encoding,
- CGM_RESTRICTED_TEXT_TYPE_BOXED_CAP,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
- _plotter->cgm_restricted_text_type =
- CGM_RESTRICTED_TEXT_TYPE_BOXED_CAP;
- _plotter->cgm_page_version = IMAX(3, _plotter->cgm_page_version);
- }
- }
-
- width = _plotter->get_text_width (R___(_plotter) s);
-
- base_vector_x = width * text_transformation_matrix[0];
- base_vector_y = width * text_transformation_matrix[1];
-
- base_width = sqrt (base_vector_x * base_vector_x + base_vector_y * base_vector_y);
-
- desired_base_width = IROUND(base_width);
-
- {
- int string_length, encoded_string_length;
- double xdev, ydev;
- int xdev_int, ydev_int;
- string_length = strlen ((const char *)s);
- encoded_string_length = CGM_BINARY_BYTES_PER_STRING(string_length);
-
- data_len = (4 * CGM_BINARY_BYTES_PER_INTEGER) + 2 + encoded_string_length;
- byte_count = data_byte_count = 0;
- xdev = XD(_plotter->drawstate->pos.x, _plotter->drawstate->pos.y);
- ydev = YD(_plotter->drawstate->pos.x, _plotter->drawstate->pos.y);
- xdev_int = IROUND(xdev);
- ydev_int = IROUND(ydev);
- _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
- CGM_GRAPHICAL_PRIMITIVE_ELEMENT, 5,
- data_len, &byte_count,
- "RESTRTEXT");
- _cgm_emit_integer (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_base_width,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_integer (_plotter->data->page, false, _plotter->cgm_encoding,
- desired_char_height,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_point (_plotter->data->page, false, _plotter->cgm_encoding,
- xdev_int, ydev_int,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_enum (_plotter->data->page, false, _plotter->cgm_encoding,
- 1,
- data_len, &data_byte_count, &byte_count,
- "final");
- _cgm_emit_string (_plotter->data->page, false, _plotter->cgm_encoding,
- (const char *)s,
- string_length, true,
- data_len, &data_byte_count, &byte_count);
- _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
- &byte_count);
-
- if (string_length > 254)
- _plotter->cgm_page_profile = IMAX(_plotter->cgm_page_profile, CGM_PROFILE_NONE);
- }
-
- return width;
- }
|