Blame canvas.c

Packit d394d9
/* Copyright (C) 2002 Bjoern Beutel. */
Packit d394d9
Packit d394d9
/* Description. =============================================================*/
Packit d394d9
Packit d394d9
/* Common routines for all Malaga GTK windows. */
Packit d394d9
Packit d394d9
/* Includes. ================================================================*/
Packit d394d9
Packit d394d9
#include <stdio.h>
Packit d394d9
#include <stdlib.h>
Packit d394d9
#include <stdarg.h>
Packit d394d9
#include <setjmp.h>
Packit d394d9
#include <string.h>
Packit d394d9
#include <math.h>
Packit d394d9
#include <time.h>
Packit d394d9
#include <errno.h>
Packit d394d9
#include <limits.h>
Packit d394d9
#include <pango/pango.h>
Packit d394d9
#include <gtk/gtk.h>
Packit d394d9
#include <gdk/gdkkeysyms.h>
Packit d394d9
#include <cairo.h>
Packit d394d9
#include "basic.h"
Packit d394d9
#include "scanner.h"
Packit d394d9
#include "input.h"
Packit d394d9
#include "files.h"
Packit d394d9
#include "canvas.h"
Packit d394d9
Packit d394d9
/* Constants. ===============================================================*/
Packit d394d9
Packit d394d9
enum {BRACKET_RATIO = 6}; /* Height:width ratio of angle brackets. */
Packit d394d9
enum {BUFFER_SIZE = 200}; /* Size of Postscript conversion buffer. */
Packit d394d9
Packit d394d9
#define CM (72.0 / 2.54) /* How many Postscript points make one centimeter. */
Packit d394d9
#define PAPER_WIDTH (20.9 * CM) /* Default width of paper. */
Packit d394d9
#define PAPER_HEIGHT (29.65 * CM) /* Default height of paper. */
Packit d394d9
#define PAPER_BORDER (1.5 * CM)
Packit d394d9
#define PAGE_WIDTH (PAPER_WIDTH - 2 * PAPER_BORDER)
Packit d394d9
#define PAGE_HEIGHT (PAPER_HEIGHT - 2 * PAPER_BORDER)
Packit d394d9
Packit d394d9
/* Hangul code points in Unicode. */
Packit d394d9
enum {FIRST_JAMO = 0x3131, 
Packit d394d9
      LAST_JAMO = 0x3163, 
Packit d394d9
      JAMO_COUNT = (LAST_JAMO - FIRST_JAMO + 1),
Packit d394d9
      FIRST_SYLLABLE = 0xac00,
Packit d394d9
      LAST_SYLLABLE = 0xd7a3,
Packit d394d9
      SYLLABLE_COUNT = (LAST_SYLLABLE - FIRST_SYLLABLE + 1)};
Packit d394d9
Packit d394d9
/* Code points in the N3F Hangul Postscript font. */
Packit d394d9
enum {FIRST_CHOSEONG = 162, CHOSEONG_COUNT = 19, NO_CHOSEONG = 161,
Packit d394d9
      FIRST_JUNGSEONG = 182, JUNGSEONG_COUNT = 21, NO_JUNGSEONG = 181, 
Packit d394d9
      FIRST_JONSEONG = 203, JONSEONG_COUNT = 28};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
/* This table maps Unicode Hangul Jamos to the N3F encoding. It starts at 
Packit d394d9
 * code point FIRST_JAMO. */
Packit d394d9
static char_t jamos[JAMO_COUNT] =
Packit d394d9
{ 
Packit d394d9
  162, 163, 205, 164, 207, 208, 165, 166, 167, 211, 212, 213, 214, 215, 216,
Packit d394d9
  217, 168, 169, 170, 220, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
Packit d394d9
  182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
Packit d394d9
  197, 198, 199, 200, 201, 202
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
/* Widths of Adobe Helvetica characters in Latin1 encoding. */
Packit d394d9
static int widths_latin1[256] = 
Packit d394d9
{
Packit d394d9
  278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 
Packit d394d9
  278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 
Packit d394d9
  278, 278, 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 
Packit d394d9
  333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 
Packit d394d9
  584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500,
Packit d394d9
  667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667,
Packit d394d9
  611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556,
Packit d394d9
  222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722,
Packit d394d9
  500, 500, 500, 334, 260, 334, 584, 278, 278, 278, 278, 278, 278, 278, 278,
Packit d394d9
  278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 333, 333, 333, 333, 333,
Packit d394d9
  333, 333, 333, 278, 333, 333, 278, 333, 333, 333, 278, 333, 556, 556, 556,
Packit d394d9
  556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, 400, 584, 333, 333,
Packit d394d9
  333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, 667, 667, 667,
Packit d394d9
  667, 667, 667,1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, 722, 722,
Packit d394d9
  778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, 556,
Packit d394d9
  556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278,
Packit d394d9
  556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 
Packit d394d9
  500
Packit d394d9
};
Packit d394d9
Packit d394d9
/* Widths of N3F-5 chars in N3F Encoding. Table starts at code point
Packit d394d9
 * FIRST_N3F. */
Packit d394d9
enum {FIRST_N3F = 161, 
Packit d394d9
      LAST_N3F = 229,
Packit d394d9
      N3F_COUNT = LAST_N3F - FIRST_N3F + 1};
Packit d394d9
static int widths_n3f[N3F_COUNT] =
Packit d394d9
{
Packit d394d9
  436, 436, 602, 436, 436, 602, 436, 436, 436, 625, 436, 663, 436, 436, 687,
Packit d394d9
  436, 436, 436, 436, 436, 80 , 370, 446, 370, 446, 286, 459, 286, 459, 80 , 
Packit d394d9
  370, 446, 268, 80 , 80 , 286, 459, 268, 80 , 80 , 268, 268, 0  , 0  , 0  ,
Packit d394d9
  0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
Packit d394d9
  0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static const char n3f_font_definition[] = 
Packit d394d9
"%%BeginResource: font n3f-5\n"
Packit d394d9
"%\n"
Packit d394d9
"% Copyright 1996, 1998 Lee Yongjae <yjlee@cglab.snu.ac.kr>\n"
Packit d394d9
"%\n"
Packit d394d9
"% Permission to use, copy, modify, and distribute this software and its\n"
Packit d394d9
"% documentation for any purpose and without fee is hereby granted,\n"
Packit d394d9
"% provided that the above copyright notice appears in all copies and\n"
Packit d394d9
"% that both, the copyright notice and this permission notice, appear in\n"
Packit d394d9
"% supporting documentation, and that the name of the copyright holder\n"
Packit d394d9
"% is not used in advertising or publicity pertaining to distribution\n"
Packit d394d9
"% of the software without specific, written prior permission.\n"
Packit d394d9
"%\n"
Packit d394d9
"12 dict begin /FontInfo 9 dict dup begin /FullName (n3f-5) readonly def\n"
Packit d394d9
"/isFixedPitch false def /Notice (Copyright 1996 Lee Yongjae) def\n"
Packit d394d9
"/ItalicAngle 0 def /UnderlinePosition -100 def /UnderlineThickness 50 def\n"
Packit d394d9
"end readonly def /FontName /n3f-5 def /Encoding 256 array 0 1 255 {1 index\n"
Packit d394d9
"exch /.notdef put} for dup 161 /k_f1 put dup 162 /k_K put dup 163 /k_Kk put\n"
Packit d394d9
"dup 164 /k_N put dup 165 /k_T put dup 166 /k_Tt put dup 167 /k_R put dup\n"
Packit d394d9
"168 /k_M put dup 169 /k_P put dup 170 /k_Pp put dup 171 /k_S put dup 172\n"
Packit d394d9
"/k_Ss put dup 173 /k_O put dup 174 /k_C put dup 175 /k_Cc put dup 176 /k_Ch\n"
Packit d394d9
"put dup 177 /k_Kh put dup 178 /k_Th put dup 179 /k_Ph put dup 180 /k_H put\n"
Packit d394d9
"dup 181 /k_f2 put dup 182 /k_a put dup 183 /k_ae put dup 184 /k_ya put dup\n"
Packit d394d9
"185 /k_yae put dup 186 /k_eo put dup 187 /k_e put dup 188 /k_yeo put dup\n"
Packit d394d9
"189 /k_ye put dup 190 /k_o put dup 191 /k_wa put dup 192 /k_wae put dup 193\n"
Packit d394d9
"/k_oe put dup 194 /k_yo put dup 195 /k_u put dup 196 /k_weo put dup 197\n"
Packit d394d9
"/k_we put dup 198 /k_wi put dup 199 /k_yu put dup 200 /k_eu put dup 201\n"
Packit d394d9
"/k_yi put dup 202 /k_i put dup 203 /k_k put dup 204 /k_kk put dup 205 /k_ks\n"
Packit d394d9
"put dup 206 /k_n put dup 207 /k_nc put dup 208 /k_nh put dup 209 /k_t put\n"
Packit d394d9
"dup 210 /k_l put dup 211 /k_lk put dup 212 /k_lm put dup 213 /k_lp put dup\n"
Packit d394d9
"214 /k_ls put dup 215 /k_lth put dup 216 /k_lph put dup 217 /k_lh put dup\n"
Packit d394d9
"218 /k_m put dup 219 /k_p put dup 220 /k_ps put dup 221 /k_s put dup 222\n"
Packit d394d9
"/k_ss put dup 223 /k_ng put dup 224 /k_c put dup 225 /k_ch put dup 226\n"
Packit d394d9
"/k_kh put dup 227 /k_th put dup 228 /k_ph put dup 229 /k_h put readonly def\n"
Packit d394d9
"/PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly\n"
Packit d394d9
"def /FontBBox { -529 -252 703 701 } readonly def /UniqueID 4030051 def\n"
Packit d394d9
"currentdict end currentfile eexec\n"
Packit d394d9
"D9D66F633B846A989B9974B0179FC6CC445BCF7C3C3333173232E3FDBFF43949\n"
Packit d394d9
"1DB866C3EF1B30F529F56D40DA3462EACD8F8BDB057A36A23611B08B42B62E04\n"
Packit d394d9
"F78389045DBF331069C7CB96640FF89489B5599FD6BE8EF25688798EC4F2C13F\n"
Packit d394d9
"431245DFF93AA4EF41E6D82885E1C6AB7F67F4BF4B809E88F7CBB013AA0CCEF4\n"
Packit d394d9
"187B2C4653946A3B5C610D2FF1E0E7D3AB43709002F44517BE09E1C3F35D2F59\n"
Packit d394d9
"70F3A4615689AA659C58AB0C3741705267C93A5D6CE9C8D3BC8F086A7492CF58\n"
Packit d394d9
"003DE8CA89A1609FA0E9E6FFF90E99BA58F8C5D720E87110453D4959E5333F1F\n"
Packit d394d9
"2B383165401D07AC9CB68B69A6C2E343001EA94177A6EFE9F6CB1DB741B84D6B\n"
Packit d394d9
"BD1E84F5175262D86AB8AB478840A805BA8BD467219CD28A5C4B3820CD173783\n"
Packit d394d9
"258C58123D0077CD375CFF73E250093D72C85E8EDE7FEE4B09F1EED41C10705D\n"
Packit d394d9
"FEA2ACC563D8471B4B266DE8E655F92D3620EEF32EB23D83FB199B98894CD857\n"
Packit d394d9
"7E035EA9C44A817375FCB4A9BCE3370EF65EE1F74A86B4EFAC30F091D4D34A3C\n"
Packit d394d9
"EEE0BF8897E6C79DF68ACE676F3F2145304CF7E6339D1EE856ADE3DFB7F9D696\n"
Packit d394d9
"2E7F000C17B4E1404C86D34ADA528F30CB522C18A00B709D05B77EF2BDD58B88\n"
Packit d394d9
"2B96C6623112C67849619CA63CB8AC370617E70FFC7FBA86E5DFFBC4B2EE6062\n"
Packit d394d9
"E701743060851BD8DB9DB790793CBF2DCEE3E5A755CFF7FCB5EB90E05899DEF7\n"
Packit d394d9
"EA3BFD6B1B6163488E883065B81AE93C4214F0F0CD360B84B337483286EC37DD\n"
Packit d394d9
"52E8DBCD28B403DDBA54E355721B6EBA71EF5B565D43BC79FD6A051673CFDBED\n"
Packit d394d9
"BEF9342B3C9157EEE4954566F87AF445C8A6CC6E5537429B2527C5F3FC38108E\n"
Packit d394d9
"BDE872FEE3F26A17EFDBB9D73B43B65CB13E24100DFA006BEB1832B9C45C642F\n"
Packit d394d9
"239155ED4ED43F0782AF636F17EB20BE8C8967E283DC6A00B15EAF8E8D239C29\n"
Packit d394d9
"944F60CB5DE69B4DF9F56EE75D274C897DB3772D7CD0E1275E30C73F0C023560\n"
Packit d394d9
"917768FE34D77039619F153CD8AC0826DF1C685DCFA7A6688008E0411FCB6EC1\n"
Packit d394d9
"5CFA71301D5162A04BC7B715282F4CC8EA0A5E7D36665DF8136D37227F139DC7\n"
Packit d394d9
"0CBFBCA56669AE03A0F69B23E7D313BB70F754419AFD2E9E8B6E2ED827D71773\n"
Packit d394d9
"24612554F335CBE16973BC44C1AADE6C2716B284777A2486BFEA7ABEE1D2E4BB\n"
Packit d394d9
"8E4FF2F56DCF2767A73599268B055E856549A52A6A775C61C4A02C6AAEF3C444\n"
Packit d394d9
"C709146DE1678608F5D46A50C126DC5E4161A67916D828E9BD8D3BEA2A834527\n"
Packit d394d9
"CEF127D99ADADE3895DFC60447332E0E34D9F34C544FCABCE014DB9E0469E1B6\n"
Packit d394d9
"9E32205941840B9BF973B5A70CFD1D2A14DAA1159517D180565ABDAB2CFB296B\n"
Packit d394d9
"AFB72AB045423ED9094F0E300B7C06E1D5C32E7315A354033E02EAAFB0BBB4E6\n"
Packit d394d9
"E4990C5C0C9D40406608B43835C76463EC08FBBF5A3742EB2AB231DC2B3DC3C0\n"
Packit d394d9
"BD7C9793C9A12FA4200E6F59DD7ABAD4C05684D1136FD2EB7ECA405596E23784\n"
Packit d394d9
"C73A815F3EFADDDE43C92BA6B1776BA381423C731F10D7F85D5853A8C9124183\n"
Packit d394d9
"EFC63F8BEC944AE48AD4917F51ED03F87755CAB6FFF549BE13F92BE50B4806B3\n"
Packit d394d9
"16A5DAD7A6F4D845E853C1CC115AB7E455293A1C911AACD1457282AF25336FDB\n"
Packit d394d9
"B94A55F79F11B7C95CA81494697BF72C8866CAD79633F0154B6D3DBADB7EE005\n"
Packit d394d9
"2A0EF550284490DD1B034946E245FC2CC1EFD485D1F376AEBDCFF96A838C3ECE\n"
Packit d394d9
"4318658747C18B728784C78289C86891300D53F4EAD5A0CF90DF91632AB92FE4\n"
Packit d394d9
"1BCD86336AF3DD0936B0CE6E4ADF70BFB767DC29F05E7F874A6366D8E63DA571\n"
Packit d394d9
"089C6C9C49625CE9FFFBB596CE078D175A6213800E59218D7B8DBFC0640CC191\n"
Packit d394d9
"DC5F095B7BD881889D00BA5B8010785626C470C7AAD7D60C054C4FF2EFE9DAEF\n"
Packit d394d9
"997FBAAD4A5C6567838A49B6634BE4AAB05A0806CAC18777E87E0DC6B078F866\n"
Packit d394d9
"E40537462E96004AC6097ED2E47A9725EF80C77DE8AE7898282200D23FCC3337\n"
Packit d394d9
"A4CDB738445AF479009B14ADEB95B2558DEF31712B8915CBD959AFC8F8390A5A\n"
Packit d394d9
"B178F926A57F6C63E84658AB33FCD3D41F3209877ADF46AD8C907C14882397C8\n"
Packit d394d9
"2B2D5A7936D0B92C149ED8A751916471BA052D1302EC62EA274F04AA667821A4\n"
Packit d394d9
"3533DCE8DD20901983D574283A68683D07E37FE59965710F8CAADCB7681DE258\n"
Packit d394d9
"E59CAB0B1793F67F686A311296B2BE7A7D10C868F8BD39A1CEF857B8A4E027FC\n"
Packit d394d9
"97BC55F1C9B2444C04C175350218C60C1944500391DDC69E7FE4455A753A66DC\n"
Packit d394d9
"E85044D657B2D71AFFBA2DB53C70BD06357B687672C78B629AECF6E7C406ED52\n"
Packit d394d9
"5539D9E2C1E7E7EB5B27A206164F06D850A1BC5E92C2CE65C0D3037EC911E440\n"
Packit d394d9
"1C738E8824D2B910C020E1650D5853A7B5D492EC1AE1E1D5C5DB26D5777F11E4\n"
Packit d394d9
"344AB9F87997D46C86C6145590C912FA35AFA2F3F96E3AE2D6A78CE53E4F1F9A\n"
Packit d394d9
"F39EDAC046ACCC5A0AB801FC11C98BDC61D689263040E9633EC3779A4D537448\n"
Packit d394d9
"F805224DC4A9CD3D1353E0D662865A0148B1C3DAC0987B5735DABF8BFF7A7084\n"
Packit d394d9
"F47978869D6CBE9505E58ED8D56784FDA1722B76E87D4DEF3C3BA4483F8AF555\n"
Packit d394d9
"ECD0017C1CBDA13C74FA98B6F1F85185404D5A37B3EA1380BB1F3DFCB977B294\n"
Packit d394d9
"3CC6EBF8C4018D782D96671D2AA125E3DF8D9AE4BAFC09B85DBDA44FA7CD6493\n"
Packit d394d9
"9589D3A258954FE2473F133AB1BDCBDFD79546E823395CDD248410C5D5CADF40\n"
Packit d394d9
"47A5758106F0A92B0AA87F5C548D791A2594A1AAC4AFE84A91DA057724857615\n"
Packit d394d9
"66633131C9A41B7C8315F04B97FBFC80B2D621F88DF6566613FCC27A08222546\n"
Packit d394d9
"6EB0859B060B93EBECE5F69976BAD8BBDB1DCF36DE6A653942A3FE1B58FE88C1\n"
Packit d394d9
"865EA81AEB3945B35AF29B6CAB2943F40936B43110376409CCE7A2BFA1A618CA\n"
Packit d394d9
"E03BA0390E6DA539C6FB4CFE82CD5ED290505C33BDA643254305E3C27288F2AE\n"
Packit d394d9
"0D22BC2C35452E5827BC119154D0953543663C4AFE36C00EF6402370E3D8C0D1\n"
Packit d394d9
"077BBA2BAB79EE3C7C8F70853EDE9E85DF996674F7A5883F3C763BAE63BB22BD\n"
Packit d394d9
"180AE2E1A7E787CE80784EBFD0240E595F9BC3D9750448E870413E0ECAB69004\n"
Packit d394d9
"03DF2D305F6EB4361942E75B0804F1609B5DE3F2C2D4A6C9543EC20F823A87A5\n"
Packit d394d9
"F695983F3FBC101C5000277D81F1EC4ADC2F105E06BC5EB528C399D138572C57\n"
Packit d394d9
"E8DC7A6F41DC6F8D44534388C30BFA963C52BC2F2F786C69BBBD405C7904ADE6\n"
Packit d394d9
"251C08F462A33A1D7D65D954299921053A87C2D8AAC2BDF9D713AD90608C6420\n"
Packit d394d9
"48AD52351B15C2211F17867244284964870D00A19B0B2378F28E232938D0DBC4\n"
Packit d394d9
"48B5FAC2207C17B6BAF3CE9EB82A315354A7EC183226EAC400067E06246BA400\n"
Packit d394d9
"B64212899C7049F4C13A8C079C2A6EA22DDFE73F4EA683B053ED02837BFA669E\n"
Packit d394d9
"BE87C0FBE2FD749D2BBB01CF22A8CBB3F4D543649B45E397F1F3ADAA57F98A3A\n"
Packit d394d9
"0F5ACF4F92541FF903DB28F9A29EB0AAE46430083913B3CD6FAA042D2EEC48A7\n"
Packit d394d9
"79CF038443F660845621E68CA56BAD5DF203A559CF770E515B726149F1821E38\n"
Packit d394d9
"017F04CF73C9B146C1BAF29BC0EA6FCB06FF083201E09C67F16441C37609FF27\n"
Packit d394d9
"5933986E314AC7FEB4CB45523CEC5F46F100D39BA02949F3F05AB76BC5E2F4FD\n"
Packit d394d9
"B91B6EFCD17E2123B260B3B954BE200FE9A6A1AEF77D8BA16CC44E3475D15289\n"
Packit d394d9
"8A6FA3D19D4CE4F3DC0325E40237647A9E2C053CBE4BEFF24F6B2E00FDA93593\n"
Packit d394d9
"176F94639A40546722168D68B5608F8CE798FC5F84D7684ABE805BAD9D8B9AF5\n"
Packit d394d9
"989C2233956A4DA479921ECBD922F882D0A94F9CF67457FA73673B65912D8410\n"
Packit d394d9
"7AC025DF0D2DDC21453C5D251505F5CD0E268C7421AD668A33C66A524B37DCAA\n"
Packit d394d9
"2F7C5557099D723FED2C7964E11D857760CEAE192FC30D685D599196324B29D9\n"
Packit d394d9
"E3A44C3448091957AD6429165A7F406E39C138680C0805D54A3CF15028EA725D\n"
Packit d394d9
"E88FA056E89108C0C1D23CA3C6A71B21B0EBA517D6FE77079B7088C0FC900101\n"
Packit d394d9
"CB2191D9ECA7A8B82B6F6DAE2FDB01EE67809232BC5C0BB2C26E828B4A6A3A30\n"
Packit d394d9
"2510326780A7A6FD6486ADD2BF76C24821791D5E1F36BAD6749A8DB20F925CFE\n"
Packit d394d9
"8D7BCF9F9EFBB8E09A48DDFF0D622E76F4F1C5A400918673FB13C241941CB237\n"
Packit d394d9
"FB2231A5C87D5B243DDB58AF892CA939AF35994BC6C9CF52972832FEC6D3B1D6\n"
Packit d394d9
"BEBB1D1D06D98F44F435108FE3E43596E5A84141609EA0C4DF97A1BF4B117EFF\n"
Packit d394d9
"B7952B3A022893E8356F8E2583B258E6738DEC7AB8EB78C35CE04495D1196156\n"
Packit d394d9
"A9829343464576E626889251A472BA52A3C8ADA9646B99EE75DC5207C54938D2\n"
Packit d394d9
"39E04F381C44D067F935426F4690FE1B6674FC367EBD5E93D151AD7880324F9B\n"
Packit d394d9
"AAD544F08F3E5911A1A47B0C2BE61C0A988D8E3E7DC05FC9C3311AE4F7E57FA7\n"
Packit d394d9
"316AFC4A7383A4C55555ABD374995B938AB0B69089420117605137B612737288\n"
Packit d394d9
"81007C3444CA68D4EAE0E0A1A240B708697456B440BCD7B598BFA428D5CD28E8\n"
Packit d394d9
"F96BA3A9D4A0C2728E89AFE02D14D1874639E163C09C71398C891CBEF3B8BA6D\n"
Packit d394d9
"CDE95EB756B8ACB762875E559267EE8EC451A3CF7E95A1D4A9EE33C87AF036FC\n"
Packit d394d9
"BFC7D0B825D86C9C277BB42D415C6D44C4F45A14320C779C1A4B0E13347B0001\n"
Packit d394d9
"1DA60DEE09061F725479C403EA4973C6D450EB15EA6D033985AAC2592B012AF6\n"
Packit d394d9
"8D2B854FFDF9BB03EC14805E251300760AD41804A8FA2821CA77794D150484EE\n"
Packit d394d9
"EA58CBB43951DC00B9493B6DC15E200BF394E19A446DBABFF71BD75CAE3D6476\n"
Packit d394d9
"E0CD659214F462A66BD348C81F97A31C3E4B8078223F00D36EC25E48D65CE127\n"
Packit d394d9
"DF09839B9FFCDE6055FC4CDB136126CFE4891C0BF7DAF9D582378845361EDDF4\n"
Packit d394d9
"93BDD1954DE5DBA70B98C462744FDE3DDDD6719BB00FF4A01136C36D20D00951\n"
Packit d394d9
"A7EB060BAEB0965A18CAD664E6DCFAA98F496704DAA6FE0787D934FFACB0E861\n"
Packit d394d9
"9753ED6BF44106206855C9E313BDC268208769E8FDD864A2A75DFFA213C0A49E\n"
Packit d394d9
"C4386F1E55F5FBD43E0AD5B3EF46531D7124D22F5080220D7DC6FF9D2E03DAF1\n"
Packit d394d9
"797544ACB18E060A04A5ABFAC6E20B8B374D606D555B6560EBCD7044B78D38DC\n"
Packit d394d9
"AAE19EEBA625224F9E016D49B6A5710CC3A0871BD3CC00265CD8E67109F7EB61\n"
Packit d394d9
"550A41FE60D2474F961264D218E302CC35205A1D655F878C8FB831DCAA33E134\n"
Packit d394d9
"70E2D2C49EAB90176513B2D1A3DB731D7207F070AAAF90B7990BA77FB559221A\n"
Packit d394d9
"855D62E824F18DF1A63DA56813CC79C4B990E87E41C4E8A9A6244E108D94D48D\n"
Packit d394d9
"A8079D448A916F68A39B5ACB375AF61C52725B1361A0FBC5818A0052F4F0B1CA\n"
Packit d394d9
"FB11446E47D6177318E3F83511BFDCE237FE94BF1223C29EF05BC57E1668A7EE\n"
Packit d394d9
"C4D9B5CAEBF4F14ABCF26719D0863FDB73DB4897E02C995DEEE70CEA14C35542\n"
Packit d394d9
"6D508B3CDD8F8A10A78F6219991D2133D77F6D6D4D346E2207F29478D8F071ED\n"
Packit d394d9
"73B331A0D41DE6B15355F85ED54AA37C502D63B9090D53F9B025877225E6FB88\n"
Packit d394d9
"6A1809D536F1F096DE2FADC386926BC07421BD0C49A01C4D77D4627BCD349528\n"
Packit d394d9
"97FC9A0D7FF60C5B705E2B1A669C938733E30BC55F03476A6B8B5CD03C3150B8\n"
Packit d394d9
"1236D235FE1E7EAFFF2FB5DFF9980328ECE0B627B4C178B6A95A4CF197611748\n"
Packit d394d9
"959878A68FBDD8857205B75524512B896357FDA8D464244646018F6078B687E3\n"
Packit d394d9
"7372A3E9792BDD3435302CB509E728BCD7B7377F2E0D5C02040033D9113AF22B\n"
Packit d394d9
"BE956919AD2CA332C1FE4B5E4D6741523A884E222FA8EFDC1C24FBBDEEF6465D\n"
Packit d394d9
"65D8A0E2C334DD806062ECB16A5BF6D24221141A2ACA31EF8AA7BA7A10ADED5C\n"
Packit d394d9
"9CC618E69EA66BE2A7A625970751BD86412514DA8441A1DBF6F0D49112A5FF88\n"
Packit d394d9
"95872BC5B995CEF7D3A27936B17E134AA66CDC3583DBA0678DFE12DFAC7514B9\n"
Packit d394d9
"52D46F914F73AB0208DB3CDDE326FFF7293CA9E3C305F8275B78E7870A50BB50\n"
Packit d394d9
"874E93D2D26A15F0FFE0D74345E536AD39ECDA53FFDA5A625001C26C97FC6FAF\n"
Packit d394d9
"F0864403FCB78C2A7EC1727DAD5BD64762086DCF5A17D4E9035123FA43C1630C\n"
Packit d394d9
"69BB2E10FAF95973AE38A13BF57A5BE8E579A43E618D4DBCAC9075D89E6CF5FF\n"
Packit d394d9
"F0DEBB17E452D336CC87DB03A3C872BC63A11F5061F7E112723E1C89ACAC5679\n"
Packit d394d9
"E7D98AA82A939FCD42CFE1BF81E87FA66FB3DEE9006B13E339FD9E034C485FA5\n"
Packit d394d9
"04812788EA8CB1A932C94645D26528CE15408B526E8EF98B1CE8363C5FC47054\n"
Packit d394d9
"8065293A984D7BB9A21F99D4BBD1B78A09FDFB18A6E8B2944D6C8D52A20E3E5F\n"
Packit d394d9
"71FDFBEB31B570D0F9D7C265338A6C5E9E0CBA742A01208D560B8FCAF15BE825\n"
Packit d394d9
"ED294D9613FCC511B62612EE6A4F35EC370A57DCC608963A73197C159FD9EB5B\n"
Packit d394d9
"F0F0AB9A86ACE51BB0C1F89029393712E1F5EFF2335512803C27524ABA13AB32\n"
Packit d394d9
"F1593B11A4996B133DD81051479A49A2459D223858A48ABBAB17E4E0B0EEE26B\n"
Packit d394d9
"0EE3EF75772268FE26F6441CE2917D18EC251DCAF7D2554B2F955FFE606957AE\n"
Packit d394d9
"2F86B7AE7CE8279638A0A3EDC3FABA38F24C4904B75262210FAC02D7A71DA8C8\n"
Packit d394d9
"C07946A02F8C24DD5A54F751A65E0ECA012F4C80C13C0AE59120AF0790B004F1\n"
Packit d394d9
"4D479EFBD046EE049B12EF9FEC70DD8196DE145A7313058A292CC7E360288C28\n"
Packit d394d9
"A596430C9B9F6A06E1C37DCAB3C9154F1F228778D77AA82126AC31F860667182\n"
Packit d394d9
"A74FF150224860B76429E3BE635A4A93CA6DDEA12E7E34501992F31DA9C55D43\n"
Packit d394d9
"214DE92977FB118F2523123FCF45C6451FAA16447108902A96C05914FC82A62A\n"
Packit d394d9
"349B3477F67C1CBCA1B3D135A649CCBC9D7BD3931EC402CAFF93974836A8E5A5\n"
Packit d394d9
"00F251261273FDE7649955FE45EA108D4B3C3895EB1E1EBC4B39DFBCAD92A245\n"
Packit d394d9
"75B09F873B851907139E6D430F4F928111414559B2FDB535DB222F8EED030F48\n"
Packit d394d9
"27EEFE50F57597190CC790B3B1B55F21433D8DC831F30B2B0F70FBDA4160F94B\n"
Packit d394d9
"36ED20D77E577E9250875DC6FC88BF280639842556AF84FF7538DCFF36D5536B\n"
Packit d394d9
"9FC9B0EFC405FF23679BC1E39FBFBCB428D5F209562BE553750DC8CD6B9F6FB6\n"
Packit d394d9
"BA9655CAEDCDE73757DEEE940C4F4FF04CA455AE8C3D94432FF9874872B77C20\n"
Packit d394d9
"71F46663493F8ACFED7B8F1C33C5C19B139A0460CBB676F523458270BA4393B9\n"
Packit d394d9
"EFFD55BD5074FB63F90827F5C9C46C9DDFA4B84AD0F48807094FC847F51C64D5\n"
Packit d394d9
"E1224E16AD882A0ED6C647E0FA2A0BBBD19F461FDA5A255BAF014599DAA755E1\n"
Packit d394d9
"18C52E7851D6651DDDD638EF488113772D52C41E135D4A4B587359C88F1BFBCB\n"
Packit d394d9
"C7925A384EFCCB35A8EA112AC298D30263A3E9A857949EE4E04BD278BEE68307\n"
Packit d394d9
"D1B351F54A233AE3FCACF2947FF6E949E6C391C24DC2CEEE5267221C30AD63C7\n"
Packit d394d9
"2E09DAAB39B2A33BD4FF51441CDAB009D0F30EED102B36C77AD3EF4C30233C61\n"
Packit d394d9
"D1ABDB13B7C9EF211DC7003B3A848DBAA7573778CC2518D8DD872106182914D0\n"
Packit d394d9
"A8E4156D99481972BDA413F9FF42BDF74BE29A49EEAD55804BD5BBB594A0D250\n"
Packit d394d9
"4B5898EE8FA5A029D850B0C6582E9EEB89B17902A94FBCBD637503C0BF334681\n"
Packit d394d9
"2BDA2CED91F072946FDE2AA824B824E628D4A229C63C8ADB8F235B77AFE501FB\n"
Packit d394d9
"91DD3B8D226DC0E69F9F68F12492F7659CB8BCC352DA9DBBC417914F6C8A291A\n"
Packit d394d9
"3EC92956A937FA07D337240B7946C311731F681281B772E330CCF5DC918D0F51\n"
Packit d394d9
"EFF203DB777EBC6267D218469675DDAD79774D0E7BCBB3C2196D8D264BC6E5CD\n"
Packit d394d9
"6E3FE1DFE75A6CDF53FB3D889A723DE8017EAD77C1E67853F9A45B091B2C2A5A\n"
Packit d394d9
"3FFB3C318024E34632220F1B2A470A2A00A1C28D5B61B8ABD95B060021D149A7\n"
Packit d394d9
"A765D00C76D38BE872BDC55EE8C43A2F98FB291ACCBA870FCAB713ED4F6D76A4\n"
Packit d394d9
"B9CB086E3B8CF4E0F1F51D43A16F56EE69373CA6D6D6AAD8B0D4DB1CF83505F5\n"
Packit d394d9
"E54133E9939074D9DE2CE82AC1F8469AFF9E6C1E43C32DC2A12367CE38141616\n"
Packit d394d9
"4726CE8AD13EF9F07DF45108F6DDD16677DAA5250C9351DCAD937E060D0E12A3\n"
Packit d394d9
"FD0858C4C2961C1E9E0DBD611B661400E40011BCF0E9EA20EA056685502399C8\n"
Packit d394d9
"4E0113757D35D7F01B753FFAF38560E6BCDAF5AF9483266645A00BC17711AC1E\n"
Packit d394d9
"D4B504AAB85349A31BD73EA6516F069A9CBF808D16EEAE065B6BED42DC799904\n"
Packit d394d9
"A9DC3B361557973754ED0FA022D82FFDBC454865A12A68216338F1BACBF8A9E7\n"
Packit d394d9
"492DB4518DEF56FDC0AE0BA3A2A20EEF538DA7804F1F223683638E1920F28756\n"
Packit d394d9
"D4926C7B9133D332502C7EE7F71EB00715704E0162ED8E1A0422FCD864F71600\n"
Packit d394d9
"CA2D1D740D45FF4E0D1235B143D1F690A019E8A57C46357207C4F7DD81747392\n"
Packit d394d9
"ADC44AEE8CB7586D7C4B4CB63753C5EB9271E27D34E6AED844212E8C203F2282\n"
Packit d394d9
"E79E8F25C16037BF85AD0DBA4E594DBC82C2FDB4B6973C4D470EE402A19B527E\n"
Packit d394d9
"BC61FC9D96C68B504CEC3406A159E2C8B6F2E79BCA75F51BBF4B61C8F5A21C56\n"
Packit d394d9
"DEADECDFAD4347200532497D3FE6FBA8E9BEC3D503A97CA50BA52CA242F6CDB1\n"
Packit d394d9
"90B6A5257BA4D9D18ABABFDABB4A65E1D5D3F6A6764D44D7CB6BF4AC888EB728\n"
Packit d394d9
"6E396FE80939AC26C8AD2A3DF3F3EEFA38544FA28F36E577B01E944E499014C5\n"
Packit d394d9
"A0F8B593151832FE49DF1EB8412012585DB9D057FBD60967893EE00D413C9FFD\n"
Packit d394d9
"3076E00DE4ECF271D390655C6C661141D894DA2362D9117D21C492F43728CA7E\n"
Packit d394d9
"8FAD31601D16CB92A7C53A4D388753E391106BD52C8FC44F364E75FB0B38895A\n"
Packit d394d9
"C67698F992012379A68AD2CD12679D5A88973B0EA80C8CD163918D8B5E9C18A0\n"
Packit d394d9
"ACB813099EC4CF63FBA34E5A1F9AF41C597FFC7843DB506CED639A1B56E77D26\n"
Packit d394d9
"3F076D4391E96A1E38D7E7F9279E7593B2E9E15FE3DB0D0F3629304D914FB012\n"
Packit d394d9
"EFD7628E50A1E9A62FDE38E67482CB5338880ACA34765DA71E7B3176F235365C\n"
Packit d394d9
"EC6F60B7201065B459AFD536A9D1605B835793B34646484E7E500A63DF569987\n"
Packit d394d9
"FB00E458300019B681E1B38DEB754C2A611E872ADEE0C300AC04341CD0410F6F\n"
Packit d394d9
"165E1004EEBA0A52DCDADB4C86ABB50529A38A509BE89A4E2A35AA7899F964F3\n"
Packit d394d9
"61297AA16F717BC2BDD79C23851618DD8FE9C15FA740A0F9D42FB8E620AF461A\n"
Packit d394d9
"8F9744F0D92888ED96B86AE357930D0D9D2DC8917D74B4F2EED482AABEF9EC6D\n"
Packit d394d9
"C1CCE9796830ED60FD27435F1280894A94C0EDD2551C1CED18B9BC713CB17537\n"
Packit d394d9
"DD797DCD049D65F9D2826AE6E19BFD3105E95E4E1B747FAE3877EC12F998A267\n"
Packit d394d9
"69E7E783FA612E70F43F551F66AB8B1F6B93B8F2A62A7EC67FA00F56EF464020\n"
Packit d394d9
"43E6286D0A40F4401DF7A6958679205B9DB58DE63FCFBD23C171F010419DB21B\n"
Packit d394d9
"42C2CE7D3F34ABD4A196A75C46363DB71CDA9CC04BF4046DE27F5CD9CF8E74B9\n"
Packit d394d9
"F440DE40658E62000A9A20F5ADD6213DA6B0915F5306BC4C9824B8E0BAC64ADE\n"
Packit d394d9
"88C1515DCCCD81CCB83E8E2E59655177EBE4DAC666C71BC21A8599BB2F533FE8\n"
Packit d394d9
"44DB822B632AA8B85D7B938C89717B13F9EC0C4975B2404389CF9B4D40DB1A73\n"
Packit d394d9
"701F3CF8FDB977AD919493746DF8952F9590E6FA4DAA82C37254BF300B65A9BC\n"
Packit d394d9
"7FB93762E42C0856C4231BB1F04A03F29FB8E70B4E909372F8F1496BA47CA82F\n"
Packit d394d9
"FBF3808CF096B1D5D7ADE9AED8872E6E8B3791311AFBB5DE7D0D8C3B0D8E9243\n"
Packit d394d9
"3BE02526125EF34F0A575E0E789B2038DF2F4ED5182EBD5CF5A9AE771F8972F7\n"
Packit d394d9
"10B6AF7BA5F0810D4E0F01465FB4A4C25F916B60CA5BA7DDE92CB24D0DE0F713\n"
Packit d394d9
"A963530BB2EA13F54C1C0FBF8D9BCB94C781FFEAEE6AE48BC951317BAB88B140\n"
Packit d394d9
"91343ACE736604B473CFC14A1845D648737C47B42EE4286CD7156C987704CEEF\n"
Packit d394d9
"FD2BFBDC4B63CE2B633C09ACC51FBEC2F8B64E815730465F5F61C1E15A1A8632\n"
Packit d394d9
"D6E55EE400D6A875D4CAF9839E53E3C28C99EBAB7E0B523D44B1270FD41FB736\n"
Packit d394d9
"1DDB0EF87AEBF2F2CE2B6DBCFDAB74A65D80E82D08F2C5F0F98F84796666FAA1\n"
Packit d394d9
"3C9399831AFA98B6D2FC37FE47C2C24E30020D85C7CB03F4EB85A6904AABB074\n"
Packit d394d9
"6E916B55F27832DD190335B88E31BE657E560A847E1E6C21CD85B2EDAF8726F9\n"
Packit d394d9
"5A1856B8D26969145B9F60E61254C57EDA7827896FFBFFC4C35F338F22175278\n"
Packit d394d9
"09C5D48862BBD55F1E4ECA3A2C6092D55D4E4AAB3542CAD1B77B2338314C7102\n"
Packit d394d9
"89BCE74F362C477ADECA09368945A337636DB7A5AED30DD64E3F3D4D1668492B\n"
Packit d394d9
"C40F67940FC90E5E64DFFBC97B23E130D387FF6FA785515AB8116FBAE382196F\n"
Packit d394d9
"B546F8B447217FD21133C1D0DAC1F45893F2A5ADFE29E73A444EC718603D0077\n"
Packit d394d9
"E69FC22A22849EBA5727C6A05FECDE20A1DE131A6D4DA9A5408147B23C320366\n"
Packit d394d9
"8D4C64678E2B71F757FF0E177219D3750F6A74A025ED156BFE446BBA3194ECD4\n"
Packit d394d9
"C71444B4E63FA0DAA81908C395C77C6484CC26E3E52D3E1D8E341C8366338254\n"
Packit d394d9
"FAEA45B6E32312C878F870B059B897F7D55F89FBE6427F40DF26310FED372B87\n"
Packit d394d9
"52E15FFA84287EB0740874FD97D090FA566FDED66372FA95D1C75DA5F2A02D42\n"
Packit d394d9
"2CED62419A1CA43FC1AA0B806866E07366BDAF329651C088EAB26D1F19A95D19\n"
Packit d394d9
"2BB46558622D6777BBC2DF431E9457A0F617B77A87F7414759FFFD66E00A16DB\n"
Packit d394d9
"9B24E997416A1BEF302768E81E252903B975275A468EC0A247BA670D8B209534\n"
Packit d394d9
"2B734D767266E2241384B5893288A0D50E12C851A47990A2BAF2445BFB7C8852\n"
Packit d394d9
"F2BA046AC935C119C3C6542AD6B5C339E11FCB55EB12BF753BB43F99E4B48317\n"
Packit d394d9
"4C3F2A0530B5AF0D89910CFBCA2290920EA1ACB34951D175D0AEF4FEAA62CE93\n"
Packit d394d9
"51F5C0ED55F0292D7F28E033D0ED773C5C5AD3E47D7DFE86C76B0C7A895F9DB6\n"
Packit d394d9
"880FE08C2008DD3C2C88FA04ABAD5D3D445ABDB5860FB48C0B973C251B138EC2\n"
Packit d394d9
"7FA2CE7F55BF4196D06AEE270858E9521D9E085C58F7561388650BEACCBC2687\n"
Packit d394d9
"C69BBDA32CFDB923EF5052D333E9BBC3549AD32CDD53F04C7D8CA21751B47ABD\n"
Packit d394d9
"C1C60A0DC155CD068EECEE0E7CA67CD539D85F2D8489C6C8F1CD0CEE611709D9\n"
Packit d394d9
"A7FACD511BF663667398082BF096D13665A1502EEDB5F0EAF00264F8A803B2B0\n"
Packit d394d9
"E47D4B4FEFF6761C382D73D2B430CA80207D8321A0A2EAD8B67EE5804022BE6C\n"
Packit d394d9
"5235002A07AFE2D1A77D467B45FD7BBFA5BD3CB3309FC140E2D55178A091A33F\n"
Packit d394d9
"5A9767BE25067AA7E12BC25AA6949F9DA0F81FB5311DF81363E117B3A383342F\n"
Packit d394d9
"3E0F4462676BE061AE4716D923B2C7BAA284A247842F6BF6E7D3901D3D3BF7A7\n"
Packit d394d9
"B4654D145D95B900EDB009C33540D3F5A4A1AE94E6BCAA3C85AC14CC197B467A\n"
Packit d394d9
"9E43E0773EBC4FD5FF73433A26C02CEEA99F515F5C15C019FA816DFB021FDCB1\n"
Packit d394d9
"047A79234BAF4952A0CC48EAED0A62EFCB4EFCCB72D4C9DF8A8803650F8543FD\n"
Packit d394d9
"714D869C0F1AC1CF5FAC20503A072372D922B9C6F14FA5D379306059C9FAF228\n"
Packit d394d9
"6AE1AAB6C87AD689AC039C11A6E74C8B7B726F671FF0BA4850FC9E06340D39A3\n"
Packit d394d9
"66A9D572B0A6A029F95B82787D2F9F40114C4B90B763DD6169678C53AFE0FB0E\n"
Packit d394d9
"105C77449EAF6F95C5C7AB06F03F3790B93617786D8AA01D92DC2F97D42CC6F1\n"
Packit d394d9
"BC68E73510AE2F22A5953493207D26117B4933BAFB8311F4298A467DEBABBC29\n"
Packit d394d9
"871532FA9C166056FB144016D341B0A864FB882C4114E7157E24FE046D5B65E7\n"
Packit d394d9
"5879DF87597BEB6224EFD2910C206589CC828C1690F40A75A99CEDB51B46B67A\n"
Packit d394d9
"C337BE8AA78C66E9652EE5C6281A0AD6432017570EBD8E9524A388360399B051\n"
Packit d394d9
"7E37544EFA2DB5A87CC52245494C8FA19844506585D3F3868934D5775F4F97C2\n"
Packit d394d9
"492FCFBE08E468BDF0E7765197104FBC00D963D0E9E0D778BAEF2C15CDCC4D6E\n"
Packit d394d9
"12E197FED3C2022A091D65D3F9F5302E7E9A280CC8A09388DD366D5083F659AF\n"
Packit d394d9
"73FB2834544914212D78ED6384EA96841ED737061D7AB0FA5B4381A38CD3EC13\n"
Packit d394d9
"AAA4E19C408992F2FC189B03839B38DC15A08305609C49C0A8C2E958DF933470\n"
Packit d394d9
"D535E5266F746FF5B5B4CD8FD3467B5AA1A1F4601E1532CA93FF14072DF2E7ED\n"
Packit d394d9
"A154A191E27D68B61D026FF5DF0AA39C398744DBF04FA587B226337D77EF11F2\n"
Packit d394d9
"2457472DC1C99E84D2E42C71A2E313EFF7E8AC506CC2BD5B585D0D58E9431DD4\n"
Packit d394d9
"F9758152794FB6D27F494AEBD3EF4250F24FF01924C3F18874F5AA64A532C8FF\n"
Packit d394d9
"77AF4A8641DA35622B07D4F964862F0B043C54555723887C5E67E192C28B2D9A\n"
Packit d394d9
"ACDE51F21B4D09D74AEA2A2B40769C4BA5F23B46E1415229CDD439007F6DED01\n"
Packit d394d9
"B4334AA5A23FF4A40D5308EA52EE0DEA1F5CEA92F9AE8A4437447FEE9464AAE6\n"
Packit d394d9
"3FDD49629AF6ABBDE4F38FC2FB9C9D152C0F64F64678D5100DC9E5C3A49FDB6B\n"
Packit d394d9
"5A56DB67D5126812B1D9269E6E9AC2A723AE9B296645459EF000FA9252EC9228\n"
Packit d394d9
"9DB18FF27595D6E952D75AC5A5DC3A48D7F40265280E263DF90E35B8F6E081B6\n"
Packit d394d9
"00633552A5BFCD6A526A46A89F8A1D7FF4F7FFABBBE1F6F4B80651B21F78B391\n"
Packit d394d9
"84B46A49F7404E8EEDC3F0B710EB231CC2CE0A8C81E27C01B1210F0E05FEB4E8\n"
Packit d394d9
"69D480F80DE0F4A1F4FD719902E82F2EDD0CEBDC764800F54D0594363E2BB797\n"
Packit d394d9
"82C1DC01960B76A9CF4B84966DD2D1E75EE1393B0ABD4E48462A195BF28B7C48\n"
Packit d394d9
"A2DFCD4163B981E785D06104F46B20F949B033C51AD5FAEE7CB3894C29E30797\n"
Packit d394d9
"FE5E6FF8C455A869DDE04686C30F8CAFF428AB5BFBAF276D90DE79A4B86455D8\n"
Packit d394d9
"8D94BF8D436BA46330A18BF55B393C926F1947AB996FC46D22CBD931427A4E81\n"
Packit d394d9
"1009C4EE608BC868A843DD888690530E1F8FADA75FC7CC0962C1DBFDEE630DCE\n"
Packit d394d9
"0BD7DC763F802548E813AE4394FC6B5CE560BF122A7D5593092C99010684070E\n"
Packit d394d9
"354201416C5E6B9E4A7F804FC89F3E50A70B6A2644329C7BCE70D2E6ABEAC786\n"
Packit d394d9
"4F2AA7361B71D289AE0EA5E11D6B8964B6AB1B03A455E775BC051BB7B6846CC1\n"
Packit d394d9
"6C292406018A00249C21CD1357EDDBFF\n"
Packit d394d9
"0000000000000000000000000000000000000000000000000000000000000000\n"
Packit d394d9
"0000000000000000000000000000000000000000000000000000000000000000\n"
Packit d394d9
"0000000000000000000000000000000000000000000000000000000000000000\n"
Packit d394d9
"0000000000000000000000000000000000000000000000000000000000000000\n"
Packit d394d9
"0000000000000000000000000000000000000000000000000000000000000000\n"
Packit d394d9
"0000000000000000000000000000000000000000000000000000000000000000\n"
Packit d394d9
"0000000000000000000000000000000000000000000000000000000000000000\n"
Packit d394d9
"cleartomark\n"
Packit d394d9
"%%EndResource\n";
Packit d394d9
Packit d394d9
/* Types. ===================================================================*/
Packit d394d9
Packit d394d9
typedef enum {GSTRING_TYPE, GRECORD_TYPE, GLIST_TYPE} gvalue_type_t;
Packit d394d9
/* Type of a node in "gvalue_t". */
Packit d394d9
Packit d394d9
typedef struct value /* A Malaga value in "malshow". */
Packit d394d9
{ 
Packit d394d9
  struct value *next; /* Next element if value is record or list element. */
Packit d394d9
  struct value *first; /* First element if value is record or list. */
Packit d394d9
  gvalue_type_t value_type; /* Type of this value. */
Packit d394d9
  PangoLayout *string; /* String (for GSTRING_TYPE). */
Packit d394d9
  PangoLayout *attribute; /* Attribute name (if record element). */
Packit d394d9
  int_t attrib_width; /* Width of attribute. */
Packit d394d9
  int_t ascent; /* Distance between top and baseline. */
Packit d394d9
  int_t width, height; /* Size of value. */
Packit d394d9
} gvalue_t;
Packit d394d9
Packit d394d9
typedef struct /* Implementation type of "pos_value_t". */
Packit d394d9
{ 
Packit d394d9
  int_t x, y, width, height, ascent;
Packit d394d9
  /* Private items follow. */
Packit d394d9
  gvalue_t *value;
Packit d394d9
} pos_value_i_t;
Packit d394d9
Packit d394d9
typedef struct /* Implementation type of "pos_string_t". */
Packit d394d9
{ 
Packit d394d9
  int_t x, y, width, height, ascent;
Packit d394d9
  /* Private items follow. */
Packit d394d9
  PangoLayout *layout;
Packit d394d9
} pos_string_i_t;
Packit d394d9
Packit d394d9
struct canvas 
Packit d394d9
{ 
Packit d394d9
  GtkWidget *window; /* Toplevel window for this canvas. */
Packit d394d9
  GtkWidget *draw_area; /* Drawing area widget. */
Packit d394d9
  GtkWidget *file_selection;
Packit d394d9
  GtkWidget *hscrollbar, *vscrollbar; /* Needed for adjust_canvas(). */
Packit d394d9
  GtkAdjustment *hadjust, *vadjust;
Packit d394d9
  GtkItemFactory *factory; /* Item factory for the pulldown menu. */
Packit d394d9
  GtkItemFactory *popup_menu_factory;
Packit d394d9
  GdkEventButton *event; /* Button press event currently handled. */
Packit d394d9
  bool_t show_hscrollbar, show_vscrollbar;
Packit d394d9
  int_t vscrollbar_width, hscrollbar_height;
Packit d394d9
  string_t ps_file_name; /* Default file name for FILE_SELECTION. */
Packit d394d9
  int_t width, height; /* Current size of canvas. */
Packit d394d9
  int_t area_width, area_height; /* Size of DRAW_AREA. */
Packit d394d9
  int_t x, y; /* Upper left corner of canvas in drawing area. */
Packit d394d9
  expose_func_t expose;
Packit d394d9
  configure_func_t configure;
Packit d394d9
  close_func_t close;
Packit d394d9
  mouse_func_t mouse_event;
Packit d394d9
  PangoFontDescription *font;
Packit d394d9
  int_t font_size; /* Selected font size. */
Packit d394d9
  int_t font_ascent; /* Ascent of FONT. */
Packit d394d9
  int_t font_height; /* Height of a line in FONT. */
Packit d394d9
  int_t space_width; /* Width of a space in FONT. */
Packit d394d9
  int_t comma_width; /* Width of a comma in FONT. */
Packit d394d9
  int_t border_width; /* Width of record border. */
Packit d394d9
  int_t line_width; /* Width of canvas lines. */
Packit d394d9
  int_t border_height; /* Height of list and record borders. */
Packit d394d9
  bool_t hanging_style; /* TRUE if values are "hanging down" from baseline. */
Packit d394d9
  bool_t alternate_cursor; /* TRUE if alternate cursor is displayed. */
Packit d394d9
  PangoLayout *comma_layout, *space_layout;
Packit d394d9
};
Packit d394d9
Packit d394d9
/* Global variables. ========================================================*/
Packit d394d9
Packit d394d9
string_t font_family;
Packit d394d9
int_t font_size;
Packit d394d9
bool_t hanging_style;
Packit d394d9
Packit d394d9
/* Variables. ===============================================================*/
Packit d394d9
Packit d394d9
/* The following variables can be shared among all canvases since there is 
Packit d394d9
 * always only one canvas being drawn. */
Packit d394d9
static char_t ps_string[ BUFFER_SIZE ]; /* Converted PostScript string. */
Packit d394d9
static GdkDrawable *drawable; /* Drawable we currently draw into. */
Packit d394d9
static cairo_t *cairo; /* Cairo context for DRAWABLE. */
Packit d394d9
static rectangle_t area; /* The clipping rectangle of DRAWABLE, using the
Packit d394d9
			  * coordinates of the whole canvas. */
Packit d394d9
static double canvas_shift; /* Shift if stroke width is odd. */
Packit d394d9
static GdkRectangle clip; /* The clipping rectangle of DRAWABLE, using the
Packit d394d9
			   * coordinates of DRAWABLE. */
Packit d394d9
static GdkGC *gc; /* Graphics context used to draw. */
Packit d394d9
static GdkColor colors[4]; /* BLACK, WHITE, RED and BLUE. */
Packit d394d9
static FILE *ps_stream; /* Stream used for PostScript output. */
Packit d394d9
static bool_t ps_mode; /* TRUE => draw into PS_STREAM; 
Packit d394d9
			* FALSE => draw into DRAWABLE. */
Packit d394d9
static bool_t use_n3f; /* TRUE iff we'll output N3F Hangul characters to
Packit d394d9
			* PS_STREAM. */
Packit d394d9
Packit d394d9
/* The following variables can be shared among all canvases since they are 
Packit d394d9
 * only set up at initialisation. */
Packit d394d9
static GdkCursor *alternate_cursor;
Packit d394d9
static PangoContext *pango_context;
Packit d394d9
Packit d394d9
/* Forward declarations. ====================================================*/
Packit d394d9
Packit d394d9
static gvalue_t *parse_value( void );
Packit d394d9
Packit d394d9
/* Parsing Malaga values. ===================================================*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
free_value( gvalue_t **value_p )
Packit d394d9
/* Free *VALUE_P. */
Packit d394d9
{
Packit d394d9
  gvalue_t *value, *next_value;
Packit d394d9
Packit d394d9
  for (value = *value_p; value != NULL; value = next_value) 
Packit d394d9
  { 
Packit d394d9
    next_value = value->next;
Packit d394d9
    free_value( &value->first );
Packit d394d9
    if (value->attribute != NULL)
Packit d394d9
      g_object_unref( value->attribute );
Packit d394d9
    if (value->string != NULL)
Packit d394d9
      g_object_unref( value->string );
Packit d394d9
    free_mem( &value );
Packit d394d9
  }
Packit d394d9
  *value_p = NULL;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static string_t
Packit d394d9
parse_symbol( void )
Packit d394d9
/* Parse a symbol and return it. */
Packit d394d9
{
Packit d394d9
  string_t symbol;
Packit d394d9
   
Packit d394d9
  test_token( TOK_IDENT );
Packit d394d9
  symbol = new_string( token_name, NULL );
Packit d394d9
  read_next_token();
Packit d394d9
  return symbol;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void value_set_string( gvalue_t *value, char_t *string ) 
Packit d394d9
{
Packit d394d9
  if (pango_context == NULL) 
Packit d394d9
    pango_context = gdk_pango_context_get(); 
Packit d394d9
Packit d394d9
  value->value_type = GSTRING_TYPE;
Packit d394d9
  value->string = pango_layout_new( pango_context );
Packit d394d9
  pango_layout_set_text( value->string, string, -1 );
Packit d394d9
  free( string );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void value_set_attribute( gvalue_t *value, char_t *attribute ) 
Packit d394d9
{
Packit d394d9
  if (pango_context == NULL) 
Packit d394d9
    pango_context = gdk_pango_context_get(); 
Packit d394d9
Packit d394d9
  value->attribute = pango_layout_new( pango_context );
Packit d394d9
  pango_layout_set_text( value->attribute, attribute, -1 );
Packit d394d9
  free( attribute );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gvalue_t *
Packit d394d9
parse_attribute_value_pair( void )
Packit d394d9
/* Parse an attribute-value pair and return a pointer to it. */
Packit d394d9
{
Packit d394d9
  string_t attribute;
Packit d394d9
  gvalue_t *new_value;
Packit d394d9
  
Packit d394d9
  if (next_token == '(') /* Read a hidden attribute. */
Packit d394d9
  { 
Packit d394d9
    read_next_token();
Packit d394d9
    attribute = parse_symbol();
Packit d394d9
    parse_token( ')' );
Packit d394d9
    new_value = new_mem( sizeof( gvalue_t ) );
Packit d394d9
    value_set_attribute( new_value, concat_strings( attribute, ":", NULL ) );
Packit d394d9
    value_set_string( new_value, new_string( "...", NULL ) );
Packit d394d9
    free_mem( &attribute );
Packit d394d9
  } 
Packit d394d9
  else 
Packit d394d9
  { 
Packit d394d9
    attribute = parse_symbol();
Packit d394d9
    parse_token( ':' );
Packit d394d9
    new_value = parse_value();
Packit d394d9
    value_set_attribute( new_value, concat_strings( attribute, ":", NULL ) );
Packit d394d9
    free_mem( &attribute );
Packit d394d9
  }
Packit d394d9
  return new_value;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gvalue_t *
Packit d394d9
parse_value( void )
Packit d394d9
/* Parse a value and return it as a "gvalue_t". */
Packit d394d9
{
Packit d394d9
  gvalue_t *new_value;
Packit d394d9
  gvalue_t *element; /* Last list or record element. */
Packit d394d9
Packit d394d9
  new_value = new_mem( sizeof( gvalue_t ) );
Packit d394d9
  switch (next_token) 
Packit d394d9
  {
Packit d394d9
  case '<':
Packit d394d9
    new_value->value_type = GLIST_TYPE;
Packit d394d9
    read_next_token();
Packit d394d9
    if (next_token != '>') 
Packit d394d9
    { 
Packit d394d9
      /* Insert NEW_VALUE as first list element. */
Packit d394d9
      new_value->first = parse_value();
Packit d394d9
      element = new_value->first;
Packit d394d9
      while (next_token == ',') 
Packit d394d9
      { 
Packit d394d9
        /* Insert NEW_VALUE as successor element. */
Packit d394d9
	read_next_token();
Packit d394d9
        element->next = parse_value();
Packit d394d9
        element = element->next;
Packit d394d9
      }
Packit d394d9
    }
Packit d394d9
    parse_token( '>' );
Packit d394d9
    break;
Packit d394d9
  case '[':
Packit d394d9
    new_value->value_type = GRECORD_TYPE;
Packit d394d9
    read_next_token();
Packit d394d9
    if (next_token != ']') 
Packit d394d9
    { 
Packit d394d9
      new_value->first = parse_attribute_value_pair();
Packit d394d9
      element = new_value->first;
Packit d394d9
      while (next_token == ',') 
Packit d394d9
      { 
Packit d394d9
	read_next_token();
Packit d394d9
        element->next = parse_attribute_value_pair();
Packit d394d9
        element = element->next;
Packit d394d9
      }
Packit d394d9
    }
Packit d394d9
    parse_token( ']' );
Packit d394d9
    break;
Packit d394d9
  case TOK_IDENT:
Packit d394d9
    value_set_string( new_value, new_string( token_name, NULL ) );
Packit d394d9
    read_next_token();
Packit d394d9
    break;
Packit d394d9
  case TOK_STRING:
Packit d394d9
    value_set_string( new_value, new_string_readable( token_string, NULL ) );
Packit d394d9
    read_next_token();
Packit d394d9
    break;
Packit d394d9
  case TOK_NUMBER:
Packit d394d9
    value_set_string( new_value, double_to_string( token_number ) );
Packit d394d9
    read_next_token();
Packit d394d9
    break;
Packit d394d9
  case '-':
Packit d394d9
    read_next_token();
Packit d394d9
    test_token( TOK_NUMBER );
Packit d394d9
    value_set_string( new_value, double_to_string( -token_number ) );
Packit d394d9
    read_next_token();
Packit d394d9
    break;
Packit d394d9
  default:
Packit d394d9
    complain( "Value expected, not \"%s\".", token_as_text( next_token ) );
Packit d394d9
  }
Packit d394d9
Packit d394d9
  return new_value;
Packit d394d9
}
Packit d394d9
Packit d394d9
/* Displaying Malaga values. ================================================*/
Packit d394d9
Packit d394d9
int_t
Packit d394d9
get_line_width( canvas_t *canvas )
Packit d394d9
/* Get line width in pixels for CANVAS. */
Packit d394d9
{
Packit d394d9
  return canvas->line_width;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
int_t
Packit d394d9
get_space_width( canvas_t *canvas )
Packit d394d9
/* Get space width in pixels for CANVAS. */
Packit d394d9
{
Packit d394d9
  return canvas->space_width;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
int_t
Packit d394d9
get_font_height( canvas_t *canvas )
Packit d394d9
/* Get font height in pixels for CANVAS. */
Packit d394d9
{
Packit d394d9
  return canvas->font_height;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
int_t
Packit d394d9
get_font_ascent( canvas_t *canvas )
Packit d394d9
/* Get number of pixels above baseline of current font for CANVAS. */
Packit d394d9
{
Packit d394d9
  return canvas->font_ascent;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
int_t 
Packit d394d9
get_border_width( canvas_t *canvas )
Packit d394d9
/* Get border width of CANVAS in pixels. */
Packit d394d9
{
Packit d394d9
  return (ps_mode ? 500 : 5);
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
set_color( color_t color )
Packit d394d9
/* Set the current drawing color to COLOR. */
Packit d394d9
{
Packit d394d9
  if (ps_mode)
Packit d394d9
  {
Packit d394d9
    if (color == WHITE) 
Packit d394d9
      fprintf( ps_stream, "1 G\n" );
Packit d394d9
    else 
Packit d394d9
      fprintf( ps_stream, "0 G\n" );
Packit d394d9
  }
Packit d394d9
  else 
Packit d394d9
  {
Packit d394d9
    gdk_gc_set_foreground( gc, &colors[ color ] );
Packit d394d9
    gdk_cairo_set_source_color( cairo, &colors[ color ] );
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static bool_t
Packit d394d9
clip_line( double *x1, double *y1, double *x2, double *y2, 
Packit d394d9
	   double x_min, double x_max )
Packit d394d9
/* Clip the x-coordinates of the line from (X1,Y1) to (X2,Y2) to the range
Packit d394d9
 * [X_MIN..X_MAX].  The start point and the end point may be swapped. */ 
Packit d394d9
{
Packit d394d9
  double t;
Packit d394d9
Packit d394d9
  /* Make sure that *X1 <= *X2. */
Packit d394d9
  if (*x2 < *x1)
Packit d394d9
  {
Packit d394d9
    t = *x1; *x1 = *x2; *x2 = t;
Packit d394d9
    t = *y1; *y1 = *y2; *y2 = t;
Packit d394d9
  }
Packit d394d9
Packit d394d9
  if (*x2 < x_min || *x1 > x_max)
Packit d394d9
    return FALSE;
Packit d394d9
Packit d394d9
  if (*x1 < x_min)
Packit d394d9
  {
Packit d394d9
    /* We can be sure that *X1 != *X2, since *X1 < X_MIN, but *X2 >= X_MIN. */
Packit d394d9
    *y1 += ((x_min - *x1) * (*y2 - *y1)) / (*x2 - *x1);
Packit d394d9
    *x1 = x_min;
Packit d394d9
  }
Packit d394d9
Packit d394d9
  if (*x2 > x_max)
Packit d394d9
  {
Packit d394d9
    /* We can be sure that *X1 != *X2, since *X2 > X_MAX, but *X1 <= X_MAX. */
Packit d394d9
    *y2 += ((x_max - *x2) * (*y2 - *y1)) / (*x2 - *x1);
Packit d394d9
    *x2 = x_max;
Packit d394d9
  }
Packit d394d9
Packit d394d9
  return TRUE;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
draw_lines_clipped( GdkPoint p[], int count )
Packit d394d9
/* Draw lines from p[0] TO p[1], p[1] TO p[2], ..., p[count-2] TO p[count-1].
Packit d394d9
 * Clip coordinates that are out of the current clip range.  
Packit d394d9
 *
Packit d394d9
 * This algorithm clips to the exact start and end points, but it cannot
Packit d394d9
 * guarantee that the line is translational invariant: If a clipped line is
Packit d394d9
 * drawn from (x1, y1) to (x2, y2) and another line from (x1 + dx, y1 + dy) to
Packit d394d9
 * (x2 + dx, y2 + dy), we cannot guarantee that, for each point (x, y) which is
Packit d394d9
 * part of the first line, the point (x + dx, y + dy) is part of the second
Packit d394d9
 * line, and vice versa. */
Packit d394d9
{
Packit d394d9
  int_t i;
Packit d394d9
  double x1, y1, x2, y2;
Packit d394d9
  const double left = clip.x - 10;
Packit d394d9
  const double right = clip.x + clip.width + 10;
Packit d394d9
  const double top = clip.y - 10;
Packit d394d9
  const double bottom = clip.y + clip.height + 10;
Packit d394d9
Packit d394d9
  for (i = 1; i < count; i++)
Packit d394d9
  {
Packit d394d9
    x1 = p[i-1].x;
Packit d394d9
    y1 = p[i-1].y;
Packit d394d9
    x2 = p[i].x;
Packit d394d9
    y2 = p[i].y;
Packit d394d9
    if (clip_line( &x1, &y1, &x2, &y2, left, right)
Packit d394d9
	&& clip_line( &y1, &x1, &y2, &x2, top, bottom))
Packit d394d9
    {
Packit d394d9
      cairo_move_to( cairo, x1 + canvas_shift, y1 + canvas_shift);
Packit d394d9
      cairo_line_to( cairo, x2 + canvas_shift , y2 + canvas_shift);
Packit d394d9
    }
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
draw_lines( int_t count, int_t x, int_t y, ... )
Packit d394d9
/* Called as "draw_lines( COUNT, x_1, y_1, x_2, y_2, ..., x_COUNT, y_COUNT )".
Packit d394d9
 * Draw lines:
Packit d394d9
 * from (x_1, y_1) to (x_2, y_2),
Packit d394d9
 * from (x_2, y_2) to (x_3, y_3),
Packit d394d9
 * ...
Packit d394d9
 * from (x_COUNT-1, y_COUNT-1) to (x_COUNT, y_COUNT). */
Packit d394d9
{
Packit d394d9
  va_list args;
Packit d394d9
  int_t i;
Packit d394d9
  static GdkPoint *p;
Packit d394d9
  static int_t max_points;
Packit d394d9
  bool_t left, right, over, under, need_clipping;
Packit d394d9
Packit d394d9
  if (ps_mode)
Packit d394d9
  {
Packit d394d9
    fprintf( ps_stream, "%d %d M ", x, area.height - y );
Packit d394d9
    va_start( args, y );
Packit d394d9
    for (i = 1; i < count; i++)
Packit d394d9
    {
Packit d394d9
      x = va_arg( args, int_t );
Packit d394d9
      y = va_arg( args, int_t );
Packit d394d9
      fprintf( ps_stream, "%d %d L ", x, area.height - y );
Packit d394d9
    }
Packit d394d9
    va_end( args );
Packit d394d9
    fprintf( ps_stream, "S\n" );
Packit d394d9
  }
Packit d394d9
  else
Packit d394d9
  {
Packit d394d9
    if (count > max_points) 
Packit d394d9
      max_points = renew_vector( &p, sizeof( GdkPoint ), count );
Packit d394d9
    left = right = over = under = FALSE;
Packit d394d9
    va_start( args, y );
Packit d394d9
    for (i = 0; ; i++)
Packit d394d9
    {
Packit d394d9
      x -= area.x;
Packit d394d9
      y -= area.y;
Packit d394d9
      if (x >= 0) 
Packit d394d9
	right = TRUE;
Packit d394d9
      if (x < area.width) 
Packit d394d9
	left = TRUE;
Packit d394d9
      if (y >= 0) 
Packit d394d9
	under = TRUE;
Packit d394d9
      if (y < area.height) 
Packit d394d9
	over = TRUE;
Packit d394d9
      x += clip.x;
Packit d394d9
      y += clip.y;
Packit d394d9
      if (x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX)
Packit d394d9
	need_clipping = TRUE;
Packit d394d9
      p[i].x = x;
Packit d394d9
      p[i].y = y;
Packit d394d9
      if (i >= count - 1) 
Packit d394d9
	break;
Packit d394d9
      x = va_arg( args, int_t );
Packit d394d9
      y = va_arg( args, int_t );
Packit d394d9
    }
Packit d394d9
    va_end( args );
Packit d394d9
    if (left && right && over && under) 
Packit d394d9
    {
Packit d394d9
      cairo_new_path( cairo );
Packit d394d9
      if (need_clipping)
Packit d394d9
	draw_lines_clipped( p, count );
Packit d394d9
      else
Packit d394d9
      {
Packit d394d9
	for (i = 0; i < count; i++)
Packit d394d9
	  cairo_line_to(cairo, p[i].x + canvas_shift, p[i].y + canvas_shift);
Packit d394d9
      }
Packit d394d9
      cairo_stroke( cairo );
Packit d394d9
    }
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
draw_rectangle( int_t x, int_t y, int_t width, int_t height )
Packit d394d9
/* Draw a rectangle with NW coordinate (X,Y), WIDTH pixels wide and HEIGHT
Packit d394d9
 * pixels high. */
Packit d394d9
{
Packit d394d9
  if (ps_mode)
Packit d394d9
  { 
Packit d394d9
    fprintf( ps_stream, "%d %d M ", x, area.height - y );
Packit d394d9
    fprintf( ps_stream, "%d %d R ", width, 0 );
Packit d394d9
    fprintf( ps_stream, "%d %d R ", 0, -height );
Packit d394d9
    fprintf( ps_stream, "%d %d R ", -width, 0 );
Packit d394d9
    fprintf( ps_stream, "F\n" );
Packit d394d9
  }
Packit d394d9
  else
Packit d394d9
  {
Packit d394d9
    x -= area.x;
Packit d394d9
    y -= area.y;
Packit d394d9
    if (x + width > 0 && x < area.width && y + height > 0 && y < area.height)
Packit d394d9
    {
Packit d394d9
      cairo_new_path( cairo );
Packit d394d9
      cairo_rectangle( cairo, 
Packit d394d9
		       clip.x + x + canvas_shift, 
Packit d394d9
		       clip.y + y + canvas_shift, 
Packit d394d9
		       width, height );
Packit d394d9
      cairo_fill( cairo );
Packit d394d9
    }
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
draw_circle( bool_t filled, int_t x, int_t y, int_t r )
Packit d394d9
{
Packit d394d9
  if (ps_mode)
Packit d394d9
  {
Packit d394d9
    if (filled) 
Packit d394d9
      fprintf( ps_stream, "%d %d %d D\n", x, area.height - y, r );
Packit d394d9
    else 
Packit d394d9
      fprintf( ps_stream, "%d %d %d C\n", x, area.height - y, r );
Packit d394d9
  }
Packit d394d9
  else
Packit d394d9
  {
Packit d394d9
    x -= area.x;
Packit d394d9
    y -= area.y;
Packit d394d9
    if (x + r >= 0 && x - r <= area.width 
Packit d394d9
	&& y + r >= 0 && y - r <= area.height)
Packit d394d9
    {
Packit d394d9
      cairo_new_path( cairo );
Packit d394d9
      cairo_arc( cairo, clip.x + x + canvas_shift, clip.y + y + canvas_shift,
Packit d394d9
		 r, 0, 2 * M_PI );
Packit d394d9
      cairo_close_path( cairo );
Packit d394d9
      if (filled) 
Packit d394d9
	cairo_fill( cairo ); 
Packit d394d9
      else 
Packit d394d9
	cairo_stroke( cairo );
Packit d394d9
    }
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
utf8_string_to_n3f( const char **string )
Packit d394d9
/* Convert *STRING (in UTF-8) to N3F PostScript string.
Packit d394d9
 * Return its length. The converted string is in PS_STRING. */
Packit d394d9
{
Packit d394d9
  int_t c, d, choseong, jungseong, jonseong;
Packit d394d9
  char *ps;
Packit d394d9
Packit d394d9
  ps = ps_string;
Packit d394d9
  while (**string != EOS && ps - ps_string < BUFFER_SIZE - 4)
Packit d394d9
  {
Packit d394d9
    c = g_utf8_get_char( *string );
Packit d394d9
    if (c >= FIRST_SYLLABLE && c <= LAST_SYLLABLE)
Packit d394d9
    {
Packit d394d9
      c -= FIRST_SYLLABLE;
Packit d394d9
      d = c / JONSEONG_COUNT;
Packit d394d9
      jonseong = c % JONSEONG_COUNT;
Packit d394d9
      jungseong = d % JUNGSEONG_COUNT;
Packit d394d9
      choseong = d / JUNGSEONG_COUNT;
Packit d394d9
      *ps++ = choseong + FIRST_CHOSEONG;
Packit d394d9
      *ps++ = jungseong + FIRST_JUNGSEONG;
Packit d394d9
      if (jonseong > 0)
Packit d394d9
	*ps++ = jonseong - 1 + FIRST_JONSEONG;
Packit d394d9
    }
Packit d394d9
    else if (c >= FIRST_JAMO && c <= LAST_JAMO)
Packit d394d9
    {
Packit d394d9
      c = jamos[ c - FIRST_JAMO ];
Packit d394d9
      *ps++ = (c < FIRST_JUNGSEONG ? c : NO_CHOSEONG);
Packit d394d9
      *ps++ = (c >= FIRST_JUNGSEONG && c < FIRST_JONSEONG ? c : NO_JUNGSEONG);
Packit d394d9
      if (c >= FIRST_JONSEONG)
Packit d394d9
	*ps++ = c;
Packit d394d9
    }
Packit d394d9
    else
Packit d394d9
      break;
Packit d394d9
    *string = g_utf8_next_char( *string );
Packit d394d9
  }
Packit d394d9
  *ps = EOS;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
utf8_string_to_latin1( const char **string )
Packit d394d9
{
Packit d394d9
  int_t c;
Packit d394d9
  char *ps;
Packit d394d9
Packit d394d9
  ps = ps_string;
Packit d394d9
  while (**string != EOS && ps - ps_string < BUFFER_SIZE - 2)
Packit d394d9
  {
Packit d394d9
    c = g_utf8_get_char( *string );
Packit d394d9
    if ((c >= 32 && c <= 126) || (c >= 160 && c <= 255))
Packit d394d9
      *ps++ = c;
Packit d394d9
    else
Packit d394d9
      break;
Packit d394d9
    *string = g_utf8_next_char( *string );
Packit d394d9
  }
Packit d394d9
  *ps = EOS;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static int_t
Packit d394d9
ps_string_width( const char *string )
Packit d394d9
{
Packit d394d9
  int_t width;
Packit d394d9
  const char *s, *old_pos;
Packit d394d9
Packit d394d9
  width = 0;
Packit d394d9
  while (*string != EOS)
Packit d394d9
  {
Packit d394d9
    old_pos = string;
Packit d394d9
Packit d394d9
    /* Convert a Latin1 segment. */
Packit d394d9
    utf8_string_to_latin1( &string );
Packit d394d9
    for (s = ps_string; *s != EOS; s++)
Packit d394d9
      width += widths_latin1[ ORD(*s) ];
Packit d394d9
Packit d394d9
    /* Convert a Hangul segment. */
Packit d394d9
    utf8_string_to_n3f( &string );
Packit d394d9
    if (*s != EOS)
Packit d394d9
      use_n3f = TRUE;
Packit d394d9
    for (s = ps_string; *s != EOS; s++)
Packit d394d9
      width += widths_n3f[ ORD(*s) - FIRST_N3F ];
Packit d394d9
Packit d394d9
    /* Ignore a non-convertible character. */
Packit d394d9
    if (string == old_pos && string != EOS)
Packit d394d9
      string = g_utf8_next_char( string );
Packit d394d9
  }
Packit d394d9
  return width;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
print_ps_text( const char *string )
Packit d394d9
/* Convert STRING to Postscript format: prefix "(", ")", and "\" with "\",
Packit d394d9
 * insert line breaks if line gets too long. */
Packit d394d9
{
Packit d394d9
  int_t col;
Packit d394d9
  const char *s, *old_pos;
Packit d394d9
Packit d394d9
  while (*string != EOS)
Packit d394d9
  {
Packit d394d9
    old_pos = string;
Packit d394d9
    /* Print a Latin1 segment. */
Packit d394d9
    utf8_string_to_latin1( &string );
Packit d394d9
    if (*ps_string != EOS)
Packit d394d9
    {
Packit d394d9
      fprintf( ps_stream, "(" );
Packit d394d9
      col = 1;
Packit d394d9
      for (s = ps_string; *s != EOS; s++)
Packit d394d9
      {
Packit d394d9
	if (col > 76) /* Insert line break if line gets too long. */
Packit d394d9
	{
Packit d394d9
	  fprintf( ps_stream, "\\\n" );
Packit d394d9
	  col = 0;
Packit d394d9
	}
Packit d394d9
	if (*s == '(' || *s == ')' || *s == '\\')
Packit d394d9
	{
Packit d394d9
	  fputc( '\\', ps_stream );
Packit d394d9
	  col++;
Packit d394d9
	}
Packit d394d9
	fputc( *s, ps_stream );
Packit d394d9
	col++;
Packit d394d9
      }
Packit d394d9
      fprintf( ps_stream, ")\nT\n" );
Packit d394d9
    }
Packit d394d9
Packit d394d9
    /* Print a Hangul segment. */
Packit d394d9
    utf8_string_to_n3f( &string );
Packit d394d9
    if (*ps_string != EOS)
Packit d394d9
    {
Packit d394d9
      fprintf( ps_stream, "<" );
Packit d394d9
      col = 1;
Packit d394d9
      for (s = ps_string; *s != EOS; s++)
Packit d394d9
      {
Packit d394d9
	if (col > 76) /* Insert line break if line gets too long. */
Packit d394d9
	{
Packit d394d9
	  fprintf( ps_stream, "\n" );
Packit d394d9
	  col = 0;
Packit d394d9
	}
Packit d394d9
	fprintf( ps_stream, "%02x", ORD( *s ) );
Packit d394d9
	col += 2;
Packit d394d9
      }
Packit d394d9
      fprintf( ps_stream, ">\nH\n" );
Packit d394d9
    }
Packit d394d9
Packit d394d9
    /* Ignore a non-convertible character. */
Packit d394d9
    if (string == old_pos && string != EOS)
Packit d394d9
      string = g_utf8_next_char( string );
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void config_layout( canvas_t *canvas, PangoLayout *layout, 
Packit d394d9
			   int_t *width, int_t *height, int_t *ascent )
Packit d394d9
{
Packit d394d9
  PangoLayoutIter *iter;
Packit d394d9
Packit d394d9
  if (ps_mode)
Packit d394d9
  {
Packit d394d9
    if (width != NULL)
Packit d394d9
      *width = ps_string_width( pango_layout_get_text( layout ) );
Packit d394d9
    if (height != NULL)
Packit d394d9
      *height = canvas->font_height;
Packit d394d9
    if (ascent != NULL)
Packit d394d9
      *ascent = canvas->font_ascent;
Packit d394d9
  }
Packit d394d9
  else
Packit d394d9
  {
Packit d394d9
    pango_layout_set_font_description( layout, canvas->font );
Packit d394d9
    pango_layout_get_pixel_size( layout, width, height );
Packit d394d9
    if (ascent != NULL)
Packit d394d9
    {
Packit d394d9
      iter = pango_layout_get_iter( layout );
Packit d394d9
      *ascent = pango_layout_iter_get_baseline( iter ) / PANGO_SCALE;
Packit d394d9
      pango_layout_iter_free( iter );
Packit d394d9
    }
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
draw_layout( canvas_t *canvas, PangoLayout *layout, int_t x, int_t y )
Packit d394d9
/* Draw LAYOUT at position (X,Y) in CANVAS. */
Packit d394d9
{
Packit d394d9
  int_t width, height;
Packit d394d9
Packit d394d9
  if (ps_mode)
Packit d394d9
  {
Packit d394d9
    fprintf( ps_stream, "%d %d M\n", 
Packit d394d9
	     x, area.height - y - canvas->font_ascent );
Packit d394d9
    print_ps_text( pango_layout_get_text( layout ) );
Packit d394d9
    return;
Packit d394d9
  }
Packit d394d9
  else
Packit d394d9
  {
Packit d394d9
    pango_layout_get_pixel_size( layout, &width, &height );
Packit d394d9
    x -= area.x;
Packit d394d9
    y -= area.y;
Packit d394d9
    if (x + width <= 0 || x >= area.width) 
Packit d394d9
      return;
Packit d394d9
    if (y + height <= 0 || y >= area.height) 
Packit d394d9
      return;
Packit d394d9
    
Packit d394d9
    gdk_draw_layout( drawable, gc, clip.x + x, clip.y + y, layout );
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
config_value( canvas_t *canvas, gvalue_t *value )
Packit d394d9
/* Compute the height, width and ascent of VALUE in CANVAS. */
Packit d394d9
{
Packit d394d9
  gvalue_t *element;
Packit d394d9
  int_t max_attrib_width, max_width, descent;
Packit d394d9
Packit d394d9
  if (value->attribute != NULL)
Packit d394d9
    config_layout( canvas, value->attribute, &value->attrib_width, NULL, NULL);
Packit d394d9
Packit d394d9
  switch (value->value_type) 
Packit d394d9
  {
Packit d394d9
  case GRECORD_TYPE:
Packit d394d9
    value->height = 0;
Packit d394d9
    max_attrib_width = 0;
Packit d394d9
    max_width = 0;
Packit d394d9
    value->ascent = canvas->border_height + canvas->font_ascent; /* Default. */
Packit d394d9
    for (element = value->first; element != NULL; element = element->next) 
Packit d394d9
    { 
Packit d394d9
      config_value( canvas, element );
Packit d394d9
      max_attrib_width = MAX( max_attrib_width, element->attrib_width );
Packit d394d9
      max_width = MAX( max_width, element->width );
Packit d394d9
Packit d394d9
      /* Update ascent and height */
Packit d394d9
      if (! canvas->hanging_style) 
Packit d394d9
      {
Packit d394d9
	value->ascent = (canvas->border_height + value->height 
Packit d394d9
			 + element->ascent);
Packit d394d9
      }
Packit d394d9
      value->height += element->height;
Packit d394d9
    }
Packit d394d9
    if (canvas->hanging_style && value->first != NULL)
Packit d394d9
      value->ascent = canvas->border_height + value->first->ascent;
Packit d394d9
    value->height = (canvas->border_height
Packit d394d9
		     + MAX( value->height, canvas->font_height )
Packit d394d9
		     + canvas->border_height);
Packit d394d9
    value->width = (canvas->border_width + max_attrib_width 
Packit d394d9
		    + canvas->space_width + max_width
Packit d394d9
		    + canvas->border_width);
Packit d394d9
    break;
Packit d394d9
  case GLIST_TYPE:
Packit d394d9
    value->width = 0;
Packit d394d9
    descent = canvas->font_height - canvas->font_ascent;
Packit d394d9
    value->ascent = canvas->font_ascent;
Packit d394d9
    for (element = value->first; element != NULL; element = element->next) 
Packit d394d9
    { 
Packit d394d9
      config_value( canvas, element );
Packit d394d9
      descent = MAX( descent, element->height - element->ascent );
Packit d394d9
      value->ascent = MAX( value->ascent, element->ascent );
Packit d394d9
      value->width += element->width;
Packit d394d9
      if (element->next != NULL) 
Packit d394d9
	value->width += (canvas->comma_width + canvas->space_width);
Packit d394d9
    }
Packit d394d9
    if (value->width == 0) 
Packit d394d9
      value->width = 2;
Packit d394d9
    value->ascent += canvas->border_height;
Packit d394d9
    value->height = value->ascent + descent + canvas->border_height; 
Packit d394d9
    value->width += 2 * (canvas->border_width / 3 
Packit d394d9
			 + ((value->height - canvas->border_height) 
Packit d394d9
			    / BRACKET_RATIO));
Packit d394d9
    break;
Packit d394d9
  case GSTRING_TYPE:
Packit d394d9
    config_layout( canvas, value->string, 
Packit d394d9
		   &value->width, &value->height, &value->ascent );
Packit d394d9
    break;
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static int_t
Packit d394d9
max_attribute_width( gvalue_t *value ) 
Packit d394d9
/* Compute maximum attribute width of record VALUE. */
Packit d394d9
{
Packit d394d9
  gvalue_t *element;
Packit d394d9
  int_t max_width;
Packit d394d9
Packit d394d9
  max_width = 0;
Packit d394d9
  for (element = value->first; element != NULL; element = element->next) 
Packit d394d9
    max_width = MAX( max_width, element->attrib_width );
Packit d394d9
  return max_width;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
draw_value( canvas_t *canvas, gvalue_t *value, int_t x, int_t y )
Packit d394d9
/* Draw VALUE in CANVAS at X/Y. */
Packit d394d9
{
Packit d394d9
  gvalue_t *element;
Packit d394d9
  int_t x2, bracket_width;
Packit d394d9
Packit d394d9
  /* If (sub)value is out of bounds, we don't need to draw it. */
Packit d394d9
  if (x >= area.x + area.width || y >= area.y + area.height
Packit d394d9
      || x + value->width <= area.x || y + value->height <= area.y) 
Packit d394d9
  { 
Packit d394d9
    return;
Packit d394d9
  }
Packit d394d9
Packit d394d9
  switch (value->value_type) 
Packit d394d9
  {
Packit d394d9
  case GRECORD_TYPE:
Packit d394d9
    /* Draw left bracket. */
Packit d394d9
    draw_lines( 4,
Packit d394d9
		x + canvas->border_width * 5 / 6,
Packit d394d9
		y + canvas->border_height / 2,
Packit d394d9
		x + canvas->border_width / 6,
Packit d394d9
		y + canvas->border_height / 2,
Packit d394d9
		x + canvas->border_width / 6,
Packit d394d9
		y + value->height - 1 - canvas->border_height / 2,
Packit d394d9
		x + canvas->border_width * 5 / 6,
Packit d394d9
		y + value->height - 1 - canvas->border_height / 2 );
Packit d394d9
Packit d394d9
    /* Draw right bracket. */
Packit d394d9
    draw_lines( 4,
Packit d394d9
		x + value->width - 1 - canvas->border_width * 5 / 6, 
Packit d394d9
		y + canvas->border_height / 2, 
Packit d394d9
		x + value->width - 1 - canvas->border_width / 6, 
Packit d394d9
		y + canvas->border_height / 2,
Packit d394d9
		x + value->width - 1 - canvas->border_width / 6, 
Packit d394d9
		y + value->height - 1 - canvas->border_height / 2,
Packit d394d9
		x + value->width - 1 - canvas->border_width * 5 / 6, 
Packit d394d9
		y + value->height - 1 - canvas->border_height / 2 );
Packit d394d9
Packit d394d9
    /* Draw elements. */
Packit d394d9
    x2 = (x + canvas->border_width + 
Packit d394d9
	  max_attribute_width( value ) + canvas->space_width);
Packit d394d9
    y += canvas->border_height;
Packit d394d9
    for (element = value->first; element != NULL; element = element->next) 
Packit d394d9
    { 
Packit d394d9
      /* Draw attribute name. */
Packit d394d9
      draw_layout( canvas, element->attribute, 
Packit d394d9
		   x + canvas->border_width, 
Packit d394d9
		   y + (element->height - canvas->font_height) / 2 );
Packit d394d9
Packit d394d9
      /* Draw attribute value. */
Packit d394d9
      draw_value( canvas, element, x2, y );
Packit d394d9
      y += element->height;
Packit d394d9
    }
Packit d394d9
    break;
Packit d394d9
  case GLIST_TYPE:
Packit d394d9
    bracket_width = (canvas->border_width / 3
Packit d394d9
		     + ((value->height - canvas->border_height) 
Packit d394d9
			/ BRACKET_RATIO));
Packit d394d9
Packit d394d9
    /* Draw left bracket. */
Packit d394d9
    draw_lines( 3,
Packit d394d9
		x + bracket_width - canvas->border_width / 6, 
Packit d394d9
		y + canvas->border_height / 2, 
Packit d394d9
		x + canvas->border_width / 6, 
Packit d394d9
		y + value->height / 2,
Packit d394d9
		x + bracket_width - canvas->border_width / 6, 
Packit d394d9
		y + value->height - 1 - canvas->border_height / 2 );
Packit d394d9
Packit d394d9
    /* Draw right bracket. */
Packit d394d9
    draw_lines( 3,
Packit d394d9
		x + value->width - 1
Packit d394d9
		- (bracket_width - canvas->border_width / 6),
Packit d394d9
		y + canvas->border_height / 2, 
Packit d394d9
		x + value->width - 1 - canvas->border_width / 6,
Packit d394d9
		y + value->height / 2,
Packit d394d9
		x + value->width - 1 
Packit d394d9
		- (bracket_width - canvas->border_width / 6),
Packit d394d9
		y + value->height - 1 - canvas->border_height / 2 );
Packit d394d9
Packit d394d9
    /* Draw elements. */
Packit d394d9
    x += bracket_width;
Packit d394d9
    y += value->ascent; /* Baseline. */
Packit d394d9
    for (element = value->first; element != NULL; element = element->next) 
Packit d394d9
    { 
Packit d394d9
      draw_value( canvas, element, x, y - element->ascent );
Packit d394d9
      x += element->width;
Packit d394d9
      if (element->next != NULL) /* Draw ",". */
Packit d394d9
      { 
Packit d394d9
	draw_layout( canvas, canvas->comma_layout, x, y - canvas->font_ascent );
Packit d394d9
        x += (canvas->comma_width + canvas->space_width);
Packit d394d9
      }
Packit d394d9
    }
Packit d394d9
    break;
Packit d394d9
  case GSTRING_TYPE:
Packit d394d9
    draw_layout( canvas, value->string, x, y );
Packit d394d9
    break;
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gboolean 
Packit d394d9
expose_event( GtkWidget *widget, GdkEventExpose *event, canvas_t *canvas ) 
Packit d394d9
{
Packit d394d9
  GdkColormap *colormap;
Packit d394d9
Packit d394d9
  if (gc == NULL)
Packit d394d9
  { 
Packit d394d9
    /* Allocate the shared graphics context and the shared colors. */
Packit d394d9
    gc = gdk_gc_new( gtk_widget_get_parent_window( canvas->draw_area ) );
Packit d394d9
    colormap = gtk_widget_get_colormap( canvas->draw_area );
Packit d394d9
Packit d394d9
    colors[ BLACK ].red = colors[ BLACK ].green = colors[ BLACK ].blue = 0;
Packit d394d9
    if (! gdk_colormap_alloc_color( colormap, &colors[ BLACK ], FALSE, TRUE ))
Packit d394d9
      complain( "Could not get black." );
Packit d394d9
Packit d394d9
    colors[ WHITE ].red = colors[ WHITE ].green = colors[ WHITE ].blue = 65535;
Packit d394d9
    if (! gdk_colormap_alloc_color( colormap, &colors[ WHITE ], FALSE, TRUE ))
Packit d394d9
      complain( "Could not get white." );
Packit d394d9
Packit d394d9
    colors[ RED ].red = 65535; colors[ RED ].green = colors[ RED ].blue = 0;
Packit d394d9
    if (! gdk_colormap_alloc_color( colormap, &colors[ RED ], FALSE, TRUE ))
Packit d394d9
      complain( "Could not get red." );
Packit d394d9
Packit d394d9
    colors[ BLUE ].blue = 65535; colors[ BLUE ].red = colors[ BLUE ].green = 0;
Packit d394d9
    if (! gdk_colormap_alloc_color( colormap, &colors[ BLUE ], FALSE, TRUE ))
Packit d394d9
      complain( "Could not get blue." );
Packit d394d9
  }
Packit d394d9
Packit d394d9
  area.x = canvas->x + event->area.x;
Packit d394d9
  area.y = canvas->y + event->area.y;
Packit d394d9
  clip.x = event->area.x;
Packit d394d9
  clip.y = event->area.y;
Packit d394d9
  clip.width = area.width = event->area.width;
Packit d394d9
  clip.height = area.height = event->area.height;
Packit d394d9
  drawable = canvas->draw_area->window;
Packit d394d9
  cairo = gdk_cairo_create(drawable);
Packit d394d9
  cairo_set_line_width( cairo, canvas->line_width );
Packit d394d9
  cairo_set_line_cap( cairo, CAIRO_LINE_CAP_SQUARE );
Packit d394d9
  cairo_set_line_join( cairo, CAIRO_LINE_JOIN_BEVEL );
Packit d394d9
  canvas->expose( canvas, &area );
Packit d394d9
  cairo_destroy(cairo);
Packit d394d9
  cairo = NULL;
Packit d394d9
Packit d394d9
  return TRUE;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
configure_draw_area( canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  if (pango_context == NULL) 
Packit d394d9
    pango_context = gdk_pango_context_get(); 
Packit d394d9
Packit d394d9
  if (canvas->comma_layout == NULL)
Packit d394d9
  {
Packit d394d9
    canvas->comma_layout = pango_layout_new( pango_context );
Packit d394d9
    pango_layout_set_text( canvas->comma_layout, ",", -1 );
Packit d394d9
  }
Packit d394d9
Packit d394d9
  if (canvas->space_layout == NULL)
Packit d394d9
  {
Packit d394d9
    canvas->space_layout = pango_layout_new( pango_context );
Packit d394d9
    pango_layout_set_text( canvas->space_layout, " ", -1 );
Packit d394d9
  }
Packit d394d9
Packit d394d9
  if (ps_mode)
Packit d394d9
  {
Packit d394d9
    canvas->border_width = 600;
Packit d394d9
    canvas->border_height = 300;
Packit d394d9
    canvas->space_width = ps_string_width( " " );
Packit d394d9
    canvas->comma_width = ps_string_width( "," );
Packit d394d9
    canvas->font_ascent = 917;
Packit d394d9
    canvas->font_height = 1150;
Packit d394d9
    canvas->line_width = 25;
Packit d394d9
  }
Packit d394d9
  else
Packit d394d9
  {
Packit d394d9
    config_layout( canvas, canvas->space_layout, &canvas->space_width, 
Packit d394d9
		   &canvas->font_height, &canvas->font_ascent );
Packit d394d9
    config_layout( canvas, canvas->comma_layout, &canvas->comma_width, 
Packit d394d9
		   NULL, NULL );
Packit d394d9
    canvas->line_width = (canvas->font_height + 8) / 12;
Packit d394d9
    canvas->border_width = 6 * canvas->line_width;
Packit d394d9
    canvas->border_height = 3 * canvas->line_width;
Packit d394d9
    canvas_shift = ((canvas->line_width & 1) != 0) ? 0.5 : 0.0;
Packit d394d9
  }
Packit d394d9
  canvas->configure( canvas, &canvas->width, &canvas->height );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
write_postscript( canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  double scaling;
Packit d394d9
  time_t now;
Packit d394d9
Packit d394d9
  area.x = 0;
Packit d394d9
  area.y = 0;
Packit d394d9
  area.width = canvas->width;
Packit d394d9
  area.height = canvas->height;
Packit d394d9
Packit d394d9
  scaling = 0.01;
Packit d394d9
  if (area.width * scaling > PAGE_WIDTH) 
Packit d394d9
    scaling = PAGE_WIDTH / (double) area.width;
Packit d394d9
  if (area.height * scaling > PAGE_HEIGHT) 
Packit d394d9
    scaling = PAGE_HEIGHT / (double) area.height;
Packit d394d9
  
Packit d394d9
  fprintf( ps_stream, 
Packit d394d9
	   "%%!PS-Adobe-3.0 EPSF-3.0\n"
Packit d394d9
	   "%%%%BoundingBox: %d %d %d %d\n",
Packit d394d9
	   (int_t) PAPER_BORDER, (int_t) PAPER_BORDER,
Packit d394d9
	   (int_t) ceil( area.width * scaling + PAPER_BORDER ), 
Packit d394d9
	   (int_t) ceil( area.height * scaling + PAPER_BORDER ) );
Packit d394d9
	   
Packit d394d9
  fprintf( ps_stream, 
Packit d394d9
	   "%%%%HiResBoundingBox: %f %f %f %f\n", 
Packit d394d9
	   PAPER_BORDER, PAPER_BORDER,
Packit d394d9
	   area.width * scaling + PAPER_BORDER, 
Packit d394d9
	   area.height * scaling + PAPER_BORDER );
Packit d394d9
Packit d394d9
  fprintf( ps_stream, 
Packit d394d9
	   "%%%%Creator: malshow\n"
Packit d394d9
	   "%%%%Title: %s\n", GTK_WINDOW( canvas->window )->title );
Packit d394d9
Packit d394d9
  time( &now );
Packit d394d9
  fprintf( ps_stream, "%%%%CreationDate: %s", ctime( &now ) );
Packit d394d9
Packit d394d9
  fprintf( ps_stream, 
Packit d394d9
	   "%%%%DocumentData: Clean8Bit\n"
Packit d394d9
	   "%%%%Orientation: Portrait\n" );
Packit d394d9
Packit d394d9
  if ( use_n3f )
Packit d394d9
    fprintf( ps_stream, "%%%%DocumentSuppliedResources: font n3f-5\n" );
Packit d394d9
Packit d394d9
  fprintf( ps_stream, 
Packit d394d9
	   "%%%%DocumentNeededResources: font Helvetica\n"
Packit d394d9
	   "%%%%EndComments\n" );
Packit d394d9
Packit d394d9
  if ( use_n3f )
Packit d394d9
    fprintf( ps_stream, "%s", n3f_font_definition );
Packit d394d9
Packit d394d9
  fprintf( ps_stream,
Packit d394d9
	   "save 11 dict begin\n"
Packit d394d9
	   "/ISOLatin1Encoding where {pop} {/ISOLatin1Encoding [\n"
Packit d394d9
	   "/space /space /space /space /space /space /space /space /space\n"
Packit d394d9
	   "/space /space /space /space /space /space /space /space /space\n"
Packit d394d9
	   "/space /space /space /space /space /space /space /space /space\n"
Packit d394d9
	   "/space /space /space /space /space /space /exclam /quotedbl\n"
Packit d394d9
	   "/numbersign /dollar /percent /ampersand /quoteright /parenleft\n"
Packit d394d9
	   "/parenright /asterisk /plus /comma /minus /period /slash /zero\n"
Packit d394d9
	   "/one /two /three /four /five /six /seven /eight /nine /colon\n"
Packit d394d9
	   "/semicolon /less /equal /greater /question /at /A /B /C /D /E /F\n"
Packit d394d9
	   "/G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z\n"
Packit d394d9
	   "/bracketleft /backslash /bracketright /asciicircum /underscore\n"
Packit d394d9
	   "/quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r\n"
Packit d394d9
	   "/s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde\n"
Packit d394d9
	   "/space /space /space /space /space /space /space /space /space\n"
Packit d394d9
	   "/space /space /space /space /space /space /space /space\n"
Packit d394d9
	   "/dotlessi /grave /acute /circumflex /tilde /macron /breve\n"
Packit d394d9
	   "/dotaccent /dieresis /space /ring /cedilla /space /hungarumlaut\n"
Packit d394d9
	   "/ogonek /caron /space /exclamdown /cent /sterling /currency /yen\n"
Packit d394d9
	   "/brokenbar /section /dieresis /copyright /ordfeminine\n"
Packit d394d9
	   "/guillemotleft /logicalnot /hyphen /registered /macron /degree\n"
Packit d394d9
	   "/plusminus /twosuperior /threesuperior /acute /mu /paragraph\n"
Packit d394d9
	   "/periodcentered /cedilla /onesuperior /ordmasculine\n"
Packit d394d9
	   "/guillemotright /onequarter /onehalf /threequarters\n"
Packit d394d9
	   "/questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis\n"
Packit d394d9
	   "/Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis\n"
Packit d394d9
	   "/Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve\n"
Packit d394d9
	   "/Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n"
Packit d394d9
	   "/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn\n"
Packit d394d9
	   "/germandbls /agrave /aacute /acircumflex /atilde /adieresis\n"
Packit d394d9
	   "/aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis\n"
Packit d394d9
	   "/igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve\n"
Packit d394d9
	   "/oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave\n"
Packit d394d9
	   "/uacute /ucircumflex /udieresis /yacute /thorn /ydieresis\n"
Packit d394d9
	   "] def} ifelse\n"
Packit d394d9
	   "/Helvetica-ISOLatin1\n"
Packit d394d9
	   "/Helvetica findfont\n" 
Packit d394d9
	   "dup length dict copy\n"
Packit d394d9
	   "dup /FID undef\n"
Packit d394d9
	   "dup /Encoding ISOLatin1Encoding put\n"
Packit d394d9
	   "definefont pop\n"
Packit d394d9
  	   "/C {0 360 arc stroke} bind def\n" /* Paint a circle. */
Packit d394d9
	   "/D {0 360 arc fill} bind def\n" /* Paint a filled disc. */
Packit d394d9
	   "/F {closepath fill} bind def\n"
Packit d394d9
	   "/G /setgray load def\n" );
Packit d394d9
Packit d394d9
  if (use_n3f)
Packit d394d9
    fprintf( ps_stream, "/H { /n3f-5 1000 selectfont show } bind def\n" );
Packit d394d9
Packit d394d9
  fprintf( ps_stream, 
Packit d394d9
	   "/L /lineto load def\n"
Packit d394d9
	   "/M /moveto load def\n"
Packit d394d9
	   "/R /rlineto load def\n"
Packit d394d9
	   "/S /stroke load def\n"
Packit d394d9
	   "/T { /Helvetica-ISOLatin1 1000 selectfont show } bind def\n" );
Packit d394d9
Packit d394d9
  fprintf( ps_stream, "%d setlinewidth\n", canvas->line_width );
Packit d394d9
  fprintf( ps_stream, "%f %f translate\n", PAPER_BORDER, PAPER_BORDER );
Packit d394d9
  fprintf( ps_stream, "%f %f scale\n", scaling, scaling );
Packit d394d9
Packit d394d9
  canvas->expose( canvas, &area );
Packit d394d9
  fprintf( ps_stream, 
Packit d394d9
	   "end restore showpage\n"
Packit d394d9
	   "%%%%EOF\n" );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
save_postscript( GtkWidget *widget, canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  GtkWidget *dialog, *label, *okay_button;  
Packit d394d9
  string_t file_name;
Packit d394d9
Packit d394d9
  file_name = (string_t) gtk_file_selection_get_filename(
Packit d394d9
    GTK_FILE_SELECTION( canvas->file_selection ) );
Packit d394d9
  TRY
Packit d394d9
  {
Packit d394d9
    ps_stream = open_stream( file_name, "w" );
Packit d394d9
    ps_mode = TRUE;
Packit d394d9
    use_n3f = FALSE;
Packit d394d9
    configure_draw_area( canvas );
Packit d394d9
    write_postscript( canvas );
Packit d394d9
    if (ferror( ps_stream )) 
Packit d394d9
      complain( "Can't write to \"%s\": %s.", strerror( errno ) );
Packit d394d9
    close_stream( &ps_stream, file_name );
Packit d394d9
    ps_mode = FALSE;
Packit d394d9
    configure_draw_area( canvas );   
Packit d394d9
  }
Packit d394d9
  IF_ERROR 
Packit d394d9
  { 
Packit d394d9
    /* Reconfigure canvas before doing any GTK stuff, so it can be safely
Packit d394d9
     * exposed. */
Packit d394d9
    close_stream( &ps_stream, NULL );
Packit d394d9
    ps_mode = FALSE;
Packit d394d9
    configure_draw_area( canvas );   
Packit d394d9
Packit d394d9
    /* Show the error message. */
Packit d394d9
    dialog = gtk_dialog_new();
Packit d394d9
    gtk_window_set_title( GTK_WINDOW( dialog ), "Export Postscript" );
Packit d394d9
    gtk_window_set_transient_for( GTK_WINDOW( dialog ),
Packit d394d9
				  GTK_WINDOW( canvas->window ) );
Packit d394d9
    gtk_window_set_position( GTK_WINDOW( dialog ), GTK_WIN_POS_MOUSE );
Packit d394d9
    label = gtk_label_new( error_text->buffer );
Packit d394d9
    gtk_misc_set_padding( GTK_MISC( label ), 10, 10 );
Packit d394d9
    okay_button = gtk_button_new_with_label( "OK" );
Packit d394d9
    gtk_signal_connect_object( GTK_OBJECT( okay_button ), "clicked",
Packit d394d9
			       GTK_SIGNAL_FUNC( gtk_widget_destroy ), 
Packit d394d9
			       GTK_OBJECT( dialog ) );
Packit d394d9
    gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->action_area ),
Packit d394d9
                       okay_button );
Packit d394d9
    gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->vbox ), label);
Packit d394d9
    gtk_widget_show_all( dialog );
Packit d394d9
    RESUME;
Packit d394d9
  }
Packit d394d9
  END_TRY;
Packit d394d9
  gtk_widget_hide( canvas->file_selection );
Packit d394d9
  canvas->file_selection = NULL;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
export_postscript( canvas_t *canvas )
Packit d394d9
/* Open "Export Postscript" selector */
Packit d394d9
{
Packit d394d9
  string_t title;
Packit d394d9
Packit d394d9
  if (canvas->file_selection == NULL)
Packit d394d9
  {
Packit d394d9
    title = concat_strings( "Export ", GTK_WINDOW( canvas->window )->title,
Packit d394d9
			    " as Postscript", NULL );
Packit d394d9
    canvas->file_selection = gtk_file_selection_new( title );
Packit d394d9
    free_mem( &title );
Packit d394d9
    gtk_window_set_transient_for( GTK_WINDOW( canvas->file_selection ),
Packit d394d9
				  GTK_WINDOW( canvas->window ) );
Packit d394d9
    gtk_window_set_position( GTK_WINDOW( canvas->file_selection ), 
Packit d394d9
			     GTK_WIN_POS_MOUSE );
Packit d394d9
    gtk_file_selection_hide_fileop_buttons(
Packit d394d9
      GTK_FILE_SELECTION( canvas->file_selection ) );
Packit d394d9
    gtk_file_selection_set_filename(
Packit d394d9
      GTK_FILE_SELECTION( canvas->file_selection ), canvas->ps_file_name );
Packit d394d9
    gtk_signal_connect( 
Packit d394d9
      GTK_OBJECT( GTK_FILE_SELECTION( canvas->file_selection )->ok_button ),
Packit d394d9
      "clicked", GTK_SIGNAL_FUNC( save_postscript ), canvas ); 
Packit d394d9
    gtk_signal_connect_object(
Packit d394d9
      GTK_OBJECT( GTK_FILE_SELECTION( 
Packit d394d9
		    canvas->file_selection )->cancel_button ),
Packit d394d9
      "clicked", GTK_SIGNAL_FUNC( gtk_widget_hide ), 
Packit d394d9
      GTK_OBJECT( canvas->file_selection ) );
Packit d394d9
    gtk_signal_connect( GTK_OBJECT( canvas->file_selection ), 
Packit d394d9
			"delete_event", GTK_SIGNAL_FUNC( gtk_widget_hide), 
Packit d394d9
			NULL );
Packit d394d9
  }
Packit d394d9
  gtk_widget_show( canvas->file_selection );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
adjust_canvas( canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  if (canvas->x + canvas->area_width > canvas->width)
Packit d394d9
    canvas->x = canvas->width - canvas->area_width;
Packit d394d9
  if (canvas->x < 0) 
Packit d394d9
    canvas->x = 0;
Packit d394d9
Packit d394d9
  if (canvas->y + canvas->area_height > canvas->height)
Packit d394d9
    canvas->y = canvas->height - canvas->area_height;
Packit d394d9
  if (canvas->y < 0) 
Packit d394d9
    canvas->y = 0;
Packit d394d9
Packit d394d9
  canvas->hadjust->value = canvas->x; 
Packit d394d9
  canvas->hadjust->upper = canvas->width;
Packit d394d9
  canvas->hadjust->page_increment = MAX( 20, canvas->area_width - 20 );
Packit d394d9
  canvas->hadjust->page_size = canvas->area_width;
Packit d394d9
Packit d394d9
  canvas->vadjust->value = canvas->y;
Packit d394d9
  canvas->vadjust->upper = canvas->height;
Packit d394d9
  canvas->vadjust->page_increment = MAX( 20, canvas->area_height - 20 );
Packit d394d9
  canvas->vadjust->page_size = canvas->area_height;
Packit d394d9
Packit d394d9
  gtk_adjustment_changed( canvas->hadjust );
Packit d394d9
  gtk_adjustment_changed( canvas->vadjust );
Packit d394d9
Packit d394d9
  /* If the pointer is currently in the drawing area, we might update the
Packit d394d9
   * cursor. */
Packit d394d9
  if (canvas->mouse_event != NULL)
Packit d394d9
  {
Packit d394d9
    int x, y;
Packit d394d9
    GdkModifierType mask;
Packit d394d9
Packit d394d9
    gdk_window_get_pointer( canvas->draw_area->window, &x, &y, &mask );
Packit d394d9
    canvas->mouse_event( canvas, canvas->x + x, canvas->y + y, 0 );
Packit d394d9
  }
Packit d394d9
Packit d394d9
  gtk_widget_queue_draw( canvas->draw_area );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gboolean
Packit d394d9
delete_event( GtkWidget *widget, GdkEvent *event, canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  hide_canvas( canvas );
Packit d394d9
  return TRUE;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gboolean
Packit d394d9
key_press_event( GtkWidget *widget, GdkEventKey *event, canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  switch (event->keyval)
Packit d394d9
  {
Packit d394d9
  case GDK_Left:
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0) 
Packit d394d9
      canvas->x = 0;
Packit d394d9
    else if ((event->state & GDK_SHIFT_MASK) != 0)
Packit d394d9
      canvas->x -= canvas->hadjust->page_increment;
Packit d394d9
    else 
Packit d394d9
      canvas->x -= 10; 
Packit d394d9
    break;
Packit d394d9
  case GDK_Right:
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0) 
Packit d394d9
      canvas->x = canvas->width;
Packit d394d9
    else if ((event->state & GDK_SHIFT_MASK) != 0)
Packit d394d9
      canvas->x += canvas->hadjust->page_increment;
Packit d394d9
    else 
Packit d394d9
      canvas->x += 10; 
Packit d394d9
    break;
Packit d394d9
  case GDK_Up: 
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0) 
Packit d394d9
      canvas->y = 0;
Packit d394d9
    else if ((event->state & GDK_SHIFT_MASK) != 0)
Packit d394d9
      canvas->y -= canvas->vadjust->page_increment; 
Packit d394d9
    else 
Packit d394d9
      canvas->y -= 10; 
Packit d394d9
    break;
Packit d394d9
  case GDK_Down: 
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0) 
Packit d394d9
      canvas->y = canvas->height;
Packit d394d9
    else if ((event->state & GDK_SHIFT_MASK) != 0)
Packit d394d9
      canvas->y += canvas->vadjust->page_increment; 
Packit d394d9
    else 
Packit d394d9
      canvas->y += 10; 
Packit d394d9
    break;
Packit d394d9
  case GDK_Home: 
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0)
Packit d394d9
      canvas->x -= canvas->hadjust->page_increment;
Packit d394d9
    else 
Packit d394d9
      canvas->x = 0; 
Packit d394d9
    break;
Packit d394d9
  case GDK_End:
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0)
Packit d394d9
      canvas->x += canvas->hadjust->page_increment;
Packit d394d9
    else 
Packit d394d9
      canvas->x = canvas->width; 
Packit d394d9
    break;
Packit d394d9
  case GDK_Page_Up:
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0) 
Packit d394d9
      canvas->y = 0;
Packit d394d9
    else 
Packit d394d9
      canvas->y -= canvas->vadjust->page_increment; 
Packit d394d9
    break;
Packit d394d9
  case GDK_Page_Down: 
Packit d394d9
    if ((event->state & GDK_CONTROL_MASK) != 0) 
Packit d394d9
      canvas->y = canvas->height;
Packit d394d9
    else 
Packit d394d9
      canvas->y += canvas->vadjust->page_increment; 
Packit d394d9
    break;
Packit d394d9
  default:
Packit d394d9
    return FALSE;
Packit d394d9
  }
Packit d394d9
  adjust_canvas( canvas );
Packit d394d9
  return TRUE;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
set_font_size( canvas_t *canvas, guint font_size )
Packit d394d9
{
Packit d394d9
  canvas->font_size = font_size;
Packit d394d9
  configure_canvas( canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
set_hanging_style( canvas_t *canvas, guint action, GtkWidget *item )
Packit d394d9
{
Packit d394d9
  canvas->hanging_style = GTK_CHECK_MENU_ITEM( item )->active;
Packit d394d9
  configure_canvas( canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
configure_scrollbars( canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  int_t width, height;
Packit d394d9
  bool_t show_hscrollbar, show_vscrollbar;
Packit d394d9
Packit d394d9
  width = canvas->area_width;
Packit d394d9
  if (canvas->show_vscrollbar)
Packit d394d9
    width += canvas->vscrollbar_width;
Packit d394d9
  show_hscrollbar = (canvas->width > width);
Packit d394d9
Packit d394d9
  height = canvas->area_height;
Packit d394d9
  if (canvas->show_hscrollbar)
Packit d394d9
    height += canvas->hscrollbar_height;
Packit d394d9
  show_vscrollbar = (canvas->height > height);
Packit d394d9
Packit d394d9
  if (show_vscrollbar && canvas->width + canvas->vscrollbar_width > width)
Packit d394d9
    show_hscrollbar = TRUE;
Packit d394d9
  if (show_hscrollbar && canvas->height + canvas->hscrollbar_height > height)
Packit d394d9
    show_vscrollbar = TRUE;
Packit d394d9
Packit d394d9
  if (show_hscrollbar != canvas->show_hscrollbar)
Packit d394d9
  {
Packit d394d9
    if (show_hscrollbar)
Packit d394d9
      gtk_widget_show( canvas->hscrollbar );
Packit d394d9
    else
Packit d394d9
      gtk_widget_hide( canvas->hscrollbar );
Packit d394d9
    canvas->show_hscrollbar = show_hscrollbar;
Packit d394d9
  }
Packit d394d9
  if (show_vscrollbar != canvas->show_vscrollbar)
Packit d394d9
  {
Packit d394d9
    if (show_vscrollbar)
Packit d394d9
      gtk_widget_show( canvas->vscrollbar );
Packit d394d9
    else
Packit d394d9
      gtk_widget_hide( canvas->vscrollbar );
Packit d394d9
    canvas->show_vscrollbar = show_vscrollbar;
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
configure_event( GtkWidget *widget, 
Packit d394d9
		 GdkEventConfigure *event, 
Packit d394d9
		 canvas_t *canvas )
Packit d394d9
/* Called if CANVAS window size has changed. */
Packit d394d9
{
Packit d394d9
  canvas->area_width = event->width;
Packit d394d9
  canvas->area_height = event->height;
Packit d394d9
  configure_scrollbars( canvas );
Packit d394d9
  adjust_canvas( canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
adjust_value_changed( GtkAdjustment *adjust, canvas_t *canvas )
Packit d394d9
/* Called if ADJUST has changed its value. Draw CANVAS at the new position. */
Packit d394d9
{
Packit d394d9
  canvas->x = canvas->hadjust->value;
Packit d394d9
  canvas->y = canvas->vadjust->value;
Packit d394d9
  gtk_widget_queue_draw( canvas->draw_area );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
make_visible( canvas_t *canvas, int_t x, int_t y )
Packit d394d9
/* Make sure the point (X,Y) is in the displayed part of CANVAS. */
Packit d394d9
{
Packit d394d9
  if (x < canvas->x || x > canvas->x + canvas->area_width)
Packit d394d9
    canvas->x =  x - canvas->area_width / 2;
Packit d394d9
  if (y < canvas->y || y > canvas->y + canvas->area_height)
Packit d394d9
    canvas->y = y - canvas->area_height / 2;
Packit d394d9
  adjust_canvas( canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
go_canvas_bottom( canvas_t *canvas )
Packit d394d9
/* Go to the bottom left of CANVAS. */
Packit d394d9
{
Packit d394d9
  canvas->x = 0;
Packit d394d9
  if (canvas->height < canvas->area_height) 
Packit d394d9
    canvas->y = 0;
Packit d394d9
  else 
Packit d394d9
    canvas->y = canvas->height - canvas->area_height;
Packit d394d9
  adjust_canvas( canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
configure_canvas( canvas_t *canvas )
Packit d394d9
/* Call this if CANVAS must be reconfigured because its content has changed
Packit d394d9
 * its size (font size change, new content, etc.). */
Packit d394d9
{
Packit d394d9
  text_t *font_descriptor;
Packit d394d9
Packit d394d9
  if (canvas->font != NULL)
Packit d394d9
    pango_font_description_free( canvas->font );
Packit d394d9
  font_descriptor = new_text();
Packit d394d9
  print_text( font_descriptor, "%s %d", font_family, canvas->font_size );
Packit d394d9
  canvas->font = pango_font_description_from_string( font_descriptor->buffer );
Packit d394d9
  free_text (&font_descriptor );
Packit d394d9
Packit d394d9
  configure_draw_area( canvas );
Packit d394d9
  configure_scrollbars( canvas );
Packit d394d9
  adjust_canvas( canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
show_canvas( canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  gdk_window_raise( canvas->window->window );
Packit d394d9
  gtk_widget_show( canvas->window );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
hide_canvas( canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  gtk_widget_hide( canvas->window );
Packit d394d9
  canvas->file_selection = NULL;
Packit d394d9
  if (canvas->close != NULL) 
Packit d394d9
    canvas->close( canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
redraw_canvas( canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  gtk_widget_queue_draw( canvas->draw_area );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
set_cursor( canvas_t *canvas, bool_t alternate )
Packit d394d9
/* Set cursor for CANVAS to alternate shape if ALTERNATE == TRUE. */
Packit d394d9
{
Packit d394d9
  if (canvas->alternate_cursor == alternate 
Packit d394d9
      || canvas->draw_area->window == NULL) 
Packit d394d9
  {
Packit d394d9
    return;
Packit d394d9
  }
Packit d394d9
  if (alternate_cursor == NULL) 
Packit d394d9
    alternate_cursor = gdk_cursor_new( GDK_HAND2 );
Packit d394d9
  gdk_window_set_cursor( canvas->draw_area->window, 
Packit d394d9
			 alternate ? alternate_cursor : NULL );
Packit d394d9
  canvas->alternate_cursor = alternate;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
set_popup_menu( canvas_t *canvas, 
Packit d394d9
		GtkItemFactoryEntry items[], int_t item_count )
Packit d394d9
/* Set a pop-up menu for CANVAS, consisting of ITEM_COUNT ITEMS. */
Packit d394d9
{
Packit d394d9
  canvas->popup_menu_factory 
Packit d394d9
    = gtk_item_factory_new( GTK_TYPE_MENU, "<main>", NULL );
Packit d394d9
  gtk_item_factory_create_items( canvas->popup_menu_factory, item_count, items,
Packit d394d9
				 canvas );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
popup_menu( canvas_t *canvas )
Packit d394d9
/* Pop up the pop-up menu for CANVAS as a reaction of a button press event that
Packit d394d9
 * is currently handled. */
Packit d394d9
{
Packit d394d9
  if (canvas->event != NULL)
Packit d394d9
  {
Packit d394d9
    gtk_item_factory_popup( canvas->popup_menu_factory, 
Packit d394d9
			    canvas->event->x_root, 
Packit d394d9
			    canvas->event->y_root,
Packit d394d9
			    canvas->event->button, 
Packit d394d9
			    canvas->event->time );
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gboolean
Packit d394d9
scroll_event( GtkWidget *widget, GdkEventScroll *event, canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  switch (event->direction)
Packit d394d9
  {
Packit d394d9
  case GDK_SCROLL_UP:
Packit d394d9
    canvas->y -= canvas->area_height / 9;
Packit d394d9
    adjust_canvas( canvas );
Packit d394d9
    return TRUE;
Packit d394d9
  case GDK_SCROLL_DOWN:
Packit d394d9
    canvas->y += canvas->area_height / 9;
Packit d394d9
    adjust_canvas( canvas );
Packit d394d9
    return TRUE;
Packit d394d9
  default:
Packit d394d9
    return FALSE;
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gboolean
Packit d394d9
button_press_event( GtkWidget *widget, GdkEventButton *event, 
Packit d394d9
		    canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  canvas->event = event;
Packit d394d9
  return canvas->mouse_event( canvas,
Packit d394d9
			      ((int_t) event->x) + canvas->x, 
Packit d394d9
			      ((int_t) event->y) + canvas->y, 
Packit d394d9
			      event->button );
Packit d394d9
  canvas->event = NULL;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gboolean
Packit d394d9
motion_notify_event( GtkWidget *widget, GdkEventMotion *event, 
Packit d394d9
		     canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  return canvas->mouse_event( canvas, 
Packit d394d9
			      ((int_t) event->x) + canvas->x, 
Packit d394d9
			      ((int_t) event->y) + canvas->y, 0 );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static gboolean
Packit d394d9
enter_notify_event( GtkWidget *widget, GdkEventCrossing *event,
Packit d394d9
		    canvas_t *canvas )
Packit d394d9
{
Packit d394d9
  return canvas->mouse_event( canvas, 
Packit d394d9
			      ((int_t) event->x) + canvas->x, 
Packit d394d9
			      ((int_t) event->y) + canvas->y, 0 );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
/* General menu items. */
Packit d394d9
static GtkItemFactoryEntry canvas_items[] = 
Packit d394d9
{
Packit d394d9
  { "/Window", NULL, NULL, 0, "<Branch>" },
Packit d394d9
  { "/Window/Export Postscript...", NULL, export_postscript, 0, NULL },
Packit d394d9
  { "/Window/Close", "<Control>C", hide_canvas, 0, NULL },
Packit d394d9
  { "/Style", NULL, NULL, 0, "<Branch>" },
Packit d394d9
  { "/Style/Font Size 8", NULL, set_font_size, 8, "<RadioItem>" },
Packit d394d9
  { "/Style/Font Size 10", NULL, set_font_size, 10, "/Style/Font Size 8" },
Packit d394d9
  { "/Style/Font Size 12", NULL, set_font_size, 12, "/Style/Font Size 8" },
Packit d394d9
  { "/Style/Font Size 14", NULL, set_font_size, 14, "/Style/Font Size 8" },
Packit d394d9
  { "/Style/Font Size 18", NULL, set_font_size, 18, "/Style/Font Size 8" },
Packit d394d9
  { "/Style/Font Size 24", NULL, set_font_size, 24, "/Style/Font Size 8" }
Packit d394d9
};
Packit d394d9
Packit d394d9
static GtkItemFactoryEntry hanging_style_items[] =
Packit d394d9
{
Packit d394d9
  { "/Style/sep1", NULL, NULL, 0, "<Separator>" },
Packit d394d9
  { "/Style/Hanging", NULL, set_hanging_style, 0, "<ToggleItem>" }
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
canvas_t *
Packit d394d9
create_canvas( string_t title,
Packit d394d9
	       string_t ps_file_name,
Packit d394d9
	       rectangle_t *geometry,
Packit d394d9
	       configure_func_t my_configure,
Packit d394d9
	       expose_func_t my_expose,
Packit d394d9
	       close_func_t my_close,
Packit d394d9
	       mouse_func_t my_mouse_event,
Packit d394d9
	       bool_t show_hanging_option,
Packit d394d9
	       GtkItemFactoryEntry items[], 
Packit d394d9
	       int_t item_count )
Packit d394d9
{
Packit d394d9
  canvas_t *canvas;
Packit d394d9
  GtkWidget *menu_bar, *vbox, *table;
Packit d394d9
  GtkAccelGroup *accel; /* Accelerator group. */
Packit d394d9
  GtkRequisition requisition;
Packit d394d9
Packit d394d9
  canvas = new_mem( sizeof( canvas_t ) );
Packit d394d9
  canvas->ps_file_name = ps_file_name;
Packit d394d9
  canvas->configure = my_configure;
Packit d394d9
  canvas->expose = my_expose;
Packit d394d9
  canvas->close = my_close;
Packit d394d9
  canvas->mouse_event = my_mouse_event;
Packit d394d9
  canvas->font_size = font_size;
Packit d394d9
Packit d394d9
  if (canvas->font_size == 0) 
Packit d394d9
    canvas->font_size = 10;
Packit d394d9
Packit d394d9
  /* Create a toplevel window. */
Packit d394d9
  canvas->window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
Packit d394d9
  gtk_signal_connect( GTK_OBJECT( canvas->window ), "delete_event",
Packit d394d9
		      GTK_SIGNAL_FUNC( delete_event ), canvas );
Packit d394d9
  gtk_window_set_title( GTK_WINDOW( canvas->window ), title );
Packit d394d9
  if (geometry->x >= 0 && geometry->y >= 0)
Packit d394d9
    gtk_window_move( GTK_WINDOW( canvas->window ), geometry->x, geometry->y );
Packit d394d9
  if (geometry->width > 0 && geometry->height > 0)
Packit d394d9
  {
Packit d394d9
    gtk_window_set_default_size( GTK_WINDOW( canvas->window), 
Packit d394d9
				 geometry->width, geometry->height );
Packit d394d9
  }
Packit d394d9
  gtk_window_set_policy( GTK_WINDOW( canvas->window ), TRUE, TRUE, FALSE );
Packit d394d9
  gtk_signal_connect( GTK_OBJECT( canvas->window ), "key_press_event",
Packit d394d9
		      GTK_SIGNAL_FUNC( key_press_event ), canvas );
Packit d394d9
Packit d394d9
  /* Fill the toplevel window with a vbox. */
Packit d394d9
  vbox = gtk_vbox_new( FALSE, 0 );
Packit d394d9
  gtk_container_add( GTK_CONTAINER( canvas->window ), vbox );
Packit d394d9
Packit d394d9
  /* Add a menu bar to the vbox. */
Packit d394d9
  accel = gtk_accel_group_new();
Packit d394d9
  canvas->factory = gtk_item_factory_new( GTK_TYPE_MENU_BAR, "<main>", accel );
Packit d394d9
  gtk_item_factory_create_items( canvas->factory, ARRAY_LENGTH( canvas_items ), 
Packit d394d9
				 canvas_items, canvas );
Packit d394d9
  if (show_hanging_option)
Packit d394d9
  {
Packit d394d9
    gtk_item_factory_create_items( canvas->factory, 
Packit d394d9
				   ARRAY_LENGTH( hanging_style_items ),  
Packit d394d9
				   hanging_style_items, canvas );
Packit d394d9
  }
Packit d394d9
  if (items != NULL)
Packit d394d9
    gtk_item_factory_create_items( canvas->factory, item_count, items, canvas );
Packit d394d9
  gtk_window_add_accel_group( GTK_WINDOW( canvas->window ), accel );
Packit d394d9
  menu_bar = gtk_item_factory_get_widget( canvas->factory, "<main>" );
Packit d394d9
  if (menu_bar == NULL) 
Packit d394d9
    complain( "Could not create menu bar." );
Packit d394d9
  gtk_box_pack_start( GTK_BOX( vbox ), menu_bar, FALSE, FALSE, 0 );
Packit d394d9
  
Packit d394d9
  /* Add a table with 2 rows and 2 columns to the vbox. */
Packit d394d9
  table = gtk_table_new( 2, 2, FALSE );
Packit d394d9
  gtk_box_pack_start_defaults( GTK_BOX( vbox ), table );
Packit d394d9
  
Packit d394d9
  /* Add a drawing area to the table in row 1, column 1. */
Packit d394d9
  canvas->draw_area = gtk_drawing_area_new();
Packit d394d9
  gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "expose_event",
Packit d394d9
		      GTK_SIGNAL_FUNC( expose_event ), canvas );
Packit d394d9
  gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "configure_event",
Packit d394d9
		      GTK_SIGNAL_FUNC( configure_event ), canvas );
Packit d394d9
  gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "scroll_event",
Packit d394d9
		      GTK_SIGNAL_FUNC( scroll_event ), canvas );
Packit d394d9
  gtk_widget_add_events( canvas->draw_area, GDK_SCROLL_MASK );
Packit d394d9
  if (my_mouse_event != NULL)
Packit d394d9
  {
Packit d394d9
    gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "button_press_event",
Packit d394d9
			GTK_SIGNAL_FUNC( button_press_event ), canvas );
Packit d394d9
    gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "motion_notify_event",
Packit d394d9
			GTK_SIGNAL_FUNC( motion_notify_event ), canvas );
Packit d394d9
    gtk_signal_connect( GTK_OBJECT( canvas->draw_area ), "enter_notify_event",
Packit d394d9
			GTK_SIGNAL_FUNC( enter_notify_event ), canvas );
Packit d394d9
    gtk_widget_add_events( canvas->draw_area, 
Packit d394d9
			   GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK
Packit d394d9
			   | GDK_ENTER_NOTIFY_MASK );
Packit d394d9
  }
Packit d394d9
  gtk_table_attach( GTK_TABLE( table ), canvas->draw_area, 0, 1, 0, 1,
Packit d394d9
		    GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0 );
Packit d394d9
  
Packit d394d9
  /* Add a vscrollbar to the table in row 1, column 2. */
Packit d394d9
  canvas->vadjust = GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 0, 10, 0, 0 ) );
Packit d394d9
  gtk_signal_connect( GTK_OBJECT( canvas->vadjust ), "value_changed",
Packit d394d9
		      GTK_SIGNAL_FUNC( adjust_value_changed ), canvas );
Packit d394d9
  canvas->vscrollbar = gtk_vscrollbar_new( canvas->vadjust );
Packit d394d9
  gtk_widget_size_request( canvas->vscrollbar, &requisition );
Packit d394d9
  canvas->vscrollbar_width = requisition.width;
Packit d394d9
  gtk_table_attach( GTK_TABLE( table ), canvas->vscrollbar, 1, 2, 0, 1,
Packit d394d9
		    0, GTK_FILL, 0, 0 );
Packit d394d9
Packit d394d9
  /* Add a hscrollbar to the table in row 2, column 1. */
Packit d394d9
  canvas->hadjust = GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 0, 10, 0, 0 ) );
Packit d394d9
  gtk_signal_connect( GTK_OBJECT( canvas->hadjust ), "value_changed",
Packit d394d9
		      GTK_SIGNAL_FUNC( adjust_value_changed ), canvas );
Packit d394d9
  canvas->hscrollbar = gtk_hscrollbar_new( canvas->hadjust );
Packit d394d9
  gtk_widget_size_request( canvas->hscrollbar, &requisition );
Packit d394d9
  canvas->hscrollbar_height = requisition.height;
Packit d394d9
  gtk_table_attach( GTK_TABLE( table ), canvas->hscrollbar, 0, 1, 1, 2,
Packit d394d9
		    GTK_FILL, 0, 0, 0 );
Packit d394d9
  
Packit d394d9
  /* Select some menu items. */
Packit d394d9
  gtk_menu_item_activate( 
Packit d394d9
    GTK_MENU_ITEM( 
Packit d394d9
      gtk_item_factory_get_item_by_action( canvas->factory, 
Packit d394d9
					   canvas->font_size ) ) );
Packit d394d9
  canvas->hanging_style = hanging_style;
Packit d394d9
  if (show_hanging_option && canvas->hanging_style)
Packit d394d9
  {
Packit d394d9
    canvas->hanging_style = TRUE;
Packit d394d9
    gtk_menu_item_activate(
Packit d394d9
      GTK_MENU_ITEM( 
Packit d394d9
	gtk_item_factory_get_item( canvas->factory, "/Style/Hanging" ) ) );
Packit d394d9
  }
Packit d394d9
Packit d394d9
  configure_canvas( canvas );
Packit d394d9
  gtk_widget_show_all( canvas->window );
Packit d394d9
  canvas->show_hscrollbar = canvas->show_vscrollbar = TRUE;
Packit d394d9
Packit d394d9
  return canvas;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
activate_menu_item( canvas_t *canvas, string_t path )
Packit d394d9
/* Activate the menu item PATH in CANVAS to VALUE. */
Packit d394d9
{
Packit d394d9
  gtk_menu_item_activate( 
Packit d394d9
    GTK_MENU_ITEM( gtk_item_factory_get_item( canvas->factory, path ) ) );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
pos_string_t *
Packit d394d9
new_pos_string( string_t string )
Packit d394d9
/* Create new POS_STRING_T with value STRING. */
Packit d394d9
{
Packit d394d9
  pos_string_i_t *pos_string_i;
Packit d394d9
Packit d394d9
  if (pango_context == NULL) 
Packit d394d9
    pango_context = gdk_pango_context_get();
Packit d394d9
  
Packit d394d9
  pos_string_i = new_mem( sizeof( pos_string_i_t ) );
Packit d394d9
  if (string != NULL)
Packit d394d9
  {
Packit d394d9
    pos_string_i->layout = pango_layout_new( pango_context );
Packit d394d9
    pango_layout_set_text( pos_string_i->layout, string, -1 );
Packit d394d9
  }
Packit d394d9
  return (pos_string_t *) pos_string_i;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
config_pos_string( pos_string_t *pos_string, canvas_t *canvas )
Packit d394d9
/* Compute size of POS_STRING in CANVAS. */
Packit d394d9
{
Packit d394d9
  pos_string_i_t *pos_string_i = (pos_string_i_t *) pos_string;
Packit d394d9
Packit d394d9
  if (pos_string_i != NULL && pos_string_i->layout != NULL)
Packit d394d9
  {
Packit d394d9
    config_layout( canvas, pos_string_i->layout, &pos_string_i->width,
Packit d394d9
		   &pos_string_i->height, &pos_string_i->ascent );
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
draw_pos_string( pos_string_t *pos_string, canvas_t *canvas )
Packit d394d9
/* Draw POS_STRING in CANVAS. */
Packit d394d9
{
Packit d394d9
  pos_string_i_t *pos_string_i = (pos_string_i_t *) pos_string;
Packit d394d9
Packit d394d9
  if (pos_string_i != NULL && pos_string_i->layout != NULL)
Packit d394d9
  {
Packit d394d9
    draw_layout( canvas, pos_string_i->layout, 
Packit d394d9
		 pos_string_i->x, pos_string_i->y );
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
free_pos_string( pos_string_t **pos_string_p )
Packit d394d9
/* Free memory allocated by "set_pos_string". */
Packit d394d9
{
Packit d394d9
  pos_string_i_t *pos_string_i = (pos_string_i_t *) *pos_string_p;
Packit d394d9
Packit d394d9
  if (pos_string_i != NULL && pos_string_i->layout != NULL)
Packit d394d9
    g_object_unref( pos_string_i->layout );
Packit d394d9
  free_mem( pos_string_p );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
pos_value_t *
Packit d394d9
parse_pos_value( void )
Packit d394d9
{
Packit d394d9
  pos_value_i_t *pos_value_i;
Packit d394d9
Packit d394d9
  pos_value_i = new_mem( sizeof( pos_value_i_t ) );
Packit d394d9
  pos_value_i->value = parse_value();
Packit d394d9
  return (pos_value_t *) pos_value_i;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
config_pos_value( pos_value_t *pos_value, canvas_t *canvas )
Packit d394d9
/* Compute size of POS_VALUE in CANVAS. */
Packit d394d9
{
Packit d394d9
  pos_value_i_t *pos_value_i = (pos_value_i_t *) pos_value;
Packit d394d9
Packit d394d9
  config_value( canvas, pos_value_i->value );
Packit d394d9
  pos_value_i->width = pos_value_i->value->width;
Packit d394d9
  pos_value_i->height = pos_value_i->value->height;
Packit d394d9
  pos_value_i->ascent = pos_value_i->value->ascent;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void 
Packit d394d9
draw_pos_value( pos_value_t *pos_value, canvas_t *canvas )
Packit d394d9
/* Draw POS_VALUE in CANVAS. */
Packit d394d9
{
Packit d394d9
  pos_value_i_t *pos_value_i = (pos_value_i_t *) pos_value;
Packit d394d9
Packit d394d9
  draw_value( canvas, pos_value_i->value, pos_value_i->x, pos_value_i->y );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
void
Packit d394d9
free_pos_value( pos_value_t **pos_value_p )
Packit d394d9
{
Packit d394d9
  pos_value_i_t *pos_value_i = (pos_value_i_t *) *pos_value_p;
Packit d394d9
Packit d394d9
  if (pos_value_i != NULL)
Packit d394d9
  {
Packit d394d9
    free_value( &pos_value_i->value );
Packit d394d9
    free_mem( pos_value_p );
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
/* End of file. =============================================================*/