grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / classes / zune / texteditor / mcc / ExportHook.c
blob678eb5ae738f0513afc452a5f93928b12864951e
1 /***************************************************************************
3 TextEditor.mcc - Textediting MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005-2014 TextEditor.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 TextEditor class Support Site: http://www.sf.net/projects/texteditor-mcc
19 $Id$
21 ***************************************************************************/
23 #include <stdio.h>
24 #include <string.h>
26 #include <exec/memory.h>
27 #include <proto/exec.h>
29 #include "private.h"
30 #include "Debug.h"
32 struct Buffer
34 STRPTR buffer;
35 STRPTR pointer;
36 ULONG flow;
37 ULONG size;
40 /// ExportHookFunc()
41 HOOKPROTONO(ExportHookFunc, STRPTR, struct ExportMessage *emsg)
43 struct Buffer *buf = emsg->UserData;
44 struct InstData *data = emsg->data;
45 STRPTR result = NULL;
47 ENTER();
49 // create a temporary buffer if we don't have one yet
50 if(buf == NULL)
52 if((buf = AllocVecShared(sizeof(*buf), MEMF_CLEAR)) != NULL)
54 if(data != NULL)
56 // respect our pool's threshold size
57 buf->buffer = AllocVecPooled(data->mypool, 512);
58 buf->size = 512;
60 else
62 buf->buffer = AllocVecShared(1024, MEMF_CLEAR);
63 buf->size = 1024;
67 if(buf != NULL)
69 buf->pointer = buf->buffer;
70 buf->flow = 0;
74 if(buf != NULL && buf->buffer != NULL)
76 LONG expand = emsg->Length * 10;
78 if(buf->buffer+buf->size < buf->pointer+expand)
80 // remember the current buffer, size and offset
81 STRPTR oldbuf = buf->buffer;
82 ULONG oldsize = buf->size;
83 ULONG offset = buf->pointer - oldbuf;
85 // allocate an expanded buffer
86 if(data != NULL)
88 // respect our pool's threshold size
89 buf->buffer = AllocVecPooled(data->mypool, oldsize+expand+512);
90 buf->size = oldsize+expand+512;
92 else
94 buf->buffer = AllocVecShared(oldsize+expand+1024, MEMF_CLEAR);
95 buf->size = oldsize+expand+1024;
98 if(buf->buffer != NULL)
100 buf->pointer = buf->buffer+offset;
102 memcpy(buf->buffer, oldbuf, offset);
104 else
106 W(DBF_BLOCK, "failed to allocate temporary buffer");
107 emsg->failure = TRUE;
110 // free the old buffer
111 if(data != NULL)
112 FreeVecPooled(data->mypool, oldbuf);
113 else
114 FreeVec(oldbuf);
117 if(emsg->failure == FALSE)
119 LONG length;
120 struct LineStyle *styles = emsg->Styles;
121 struct LineColor *colors = emsg->Colors;
122 LONG lastpos = 0;
123 UWORD currentstyle = 0;
124 ULONG hookType = (IPTR)hook->h_Data;
125 STRPTR startx;
127 // if this hook is of plain type we have consider highlighting as well.
128 if(hookType == MUIV_TextEditor_ExportHook_Plain && emsg->Highlight == TRUE)
130 *buf->pointer++ = '\033';
131 *buf->pointer++ = 'h';
134 if(hookType == MUIV_TextEditor_ExportHook_Plain && emsg->Flow != buf->flow)
136 *buf->pointer++ = '\033';
138 switch(emsg->Flow)
140 case MUIV_TextEditor_Flow_Right:
141 *buf->pointer++ = 'r';
142 break;
144 case MUIV_TextEditor_Flow_Center:
145 *buf->pointer++ = 'c';
146 break;
148 case MUIV_TextEditor_Flow_Left:
149 default:
150 *buf->pointer++ = 'l';
151 break;
154 buf->flow = emsg->Flow;
157 if(emsg->Separator != LNSF_None)
159 if(hookType == MUIV_TextEditor_ExportHook_Plain)
160 snprintf(buf->pointer, buf->size-(buf->pointer-buf->buffer), "\033[s:%d]", emsg->Separator);
161 else
162 strlcpy(buf->pointer, isFlagSet(emsg->Separator, LNSF_Thick) ? "<tsb>" : "<sb>", buf->size-(buf->pointer-buf->buffer));
164 buf->pointer += strlen(buf->pointer);
167 // define some start values.
168 startx = buf->pointer;
169 length = emsg->Length-emsg->SkipFront-emsg->SkipBack;
170 lastpos = emsg->SkipFront;
172 if((styles != NULL || colors != NULL) &&
173 (hookType == MUIV_TextEditor_ExportHook_EMail || hookType == MUIV_TextEditor_ExportHook_Plain))
175 LONG pos;
176 WORD style;
177 BOOL coloured = FALSE;
178 UWORD colour_state = 7;
179 LONG nextStyleColumn;
180 LONG nextColorColumn;
182 if(styles == NULL)
183 nextStyleColumn = EOS;
184 else
185 nextStyleColumn = styles[0].column;
187 if(colors == NULL)
188 nextColorColumn = EOC;
189 else
190 nextColorColumn = colors[0].column;
192 while(length > 0 && (nextStyleColumn != EOS || nextColorColumn != EOC))
194 BOOL isColorChange;
195 LONG len;
197 SHOWVALUE(DBF_EXPORT, nextStyleColumn);
198 SHOWVALUE(DBF_EXPORT, nextColorColumn);
200 // check whether a style change or a color change is first to be handled
201 if((coloured == TRUE && nextStyleColumn < nextColorColumn) ||
202 (coloured == FALSE && nextStyleColumn <= nextColorColumn))
204 pos = styles->column - 1;
205 style = styles->style;
206 isColorChange = FALSE;
207 // remember the next style change column
208 styles++;
209 nextStyleColumn = styles->column;
211 else
213 pos = colors->column - 1;
214 style = colors->color;
215 isColorChange = TRUE;
216 // remember the next style change column
217 colors++;
218 nextColorColumn = colors->column;
221 // skip styles&colors which below lastpos
222 if(pos < lastpos)
223 continue;
225 // depending on how much we export
226 // we have to fire up the style convert routines.
227 if(pos-lastpos <= length)
229 len = pos-lastpos;
230 memcpy(buf->pointer, emsg->Contents+lastpos, len);
231 buf->pointer += len;
233 if(hookType == MUIV_TextEditor_ExportHook_EMail)
235 if(isColorChange == TRUE)
237 if((coloured = (style == colour_state ? TRUE : FALSE)))
239 *buf->pointer++ = '#';
240 colour_state ^= 7;
243 else
245 switch(style)
247 case UNDERLINE:
248 case ~UNDERLINE:
250 *buf->pointer++ = '_';
252 break;
254 case BOLD:
255 case ~BOLD:
257 *buf->pointer++ = '*';
259 break;
261 case ITALIC:
262 case ~ITALIC:
264 *buf->pointer++ = '/';
266 break;
270 else if(hookType == MUIV_TextEditor_ExportHook_Plain)
272 if(isColorChange == TRUE)
274 D(DBF_EXPORT, "exporting color %ld of column %ld", style, pos+1);
275 snprintf(buf->pointer, buf->size-(buf->pointer-buf->buffer), "\033p[%d]", style);
276 buf->pointer += strlen(buf->pointer);
278 else
280 switch(style)
282 case BOLD:
284 D(DBF_EXPORT, "exporting bold style of column %ld", pos+1);
285 *buf->pointer++ = '\033';
286 *buf->pointer++ = 'b';
287 setFlag(currentstyle, BOLD);
289 break;
291 case ITALIC:
293 D(DBF_EXPORT, "exporting italic style of column %ld", pos+1);
294 *buf->pointer++ = '\033';
295 *buf->pointer++ = 'i';
296 setFlag(currentstyle, ITALIC);
298 break;
300 case UNDERLINE:
302 D(DBF_EXPORT, "exporting underline style of column %ld", pos+1);
303 *buf->pointer++ = '\033';
304 *buf->pointer++ = 'u';
305 setFlag(currentstyle, UNDERLINE);
307 break;
309 case ~BOLD:
310 case ~ITALIC:
311 case ~UNDERLINE:
313 currentstyle &= style;
315 if(pos+1 != styles->column || styles->style < 0x8000)
317 D(DBF_EXPORT, "exporting plain style of column %ld", pos+1);
318 *buf->pointer++ = '\033';
319 *buf->pointer++ = 'n';
321 if(isFlagSet(currentstyle, UNDERLINE))
323 *buf->pointer++ = '\033';
324 *buf->pointer++ = 'u';
327 if(isFlagSet(currentstyle, BOLD))
329 *buf->pointer++ = '\033';
330 *buf->pointer++ = 'b';
333 if(isFlagSet(currentstyle, ITALIC))
335 *buf->pointer++ = '\033';
336 *buf->pointer++ = 'i';
340 break;
345 else
347 len = length;
348 memcpy(buf->pointer, emsg->Contents+lastpos, len);
349 buf->pointer += len;
352 length -= len;
354 if(length == -1)
355 length = 0;
357 lastpos = pos;
361 if(length > 0)
363 memcpy(buf->pointer, emsg->Contents+lastpos, length);
364 buf->pointer += length;
367 // NUL terminate our buffer string
368 *buf->pointer = '\0';
370 while(emsg->ExportWrap != 0 && buf->pointer-startx > emsg->ExportWrap)
372 LONG max = emsg->ExportWrap+1;
374 if(startx[emsg->ExportWrap] != '\n')
376 while(--max && *(startx+max) != ' ')
377 ; // empty while
380 if(max)
382 *(startx += max) = '\n';
384 else
386 while(++startx < buf->pointer && *(startx) != ' ')
387 ; // empty while
389 if(buf->pointer != startx)
391 *startx = '\n';
397 if(emsg->Last == TRUE)
399 // free the temporary struct after we processed the last line
400 result = buf->buffer;
401 FreeVec(buf);
403 else
405 // return the temporary struct for the next call
406 result = (STRPTR)buf;
409 else
411 W(DBF_BLOCK, "failed to allocate temporary buffer");
412 SHOWVALUE(DBF_BLOCK, buf);
413 if(buf != NULL)
414 SHOWVALUE(DBF_BLOCK, buf->buffer);
415 emsg->failure = TRUE;
418 RETURN(result);
419 return result;
422 MakeHookWithData(ExportHookPlain, ExportHookFunc, MUIV_TextEditor_ExportHook_Plain);
423 MakeHookWithData(ExportHookEMail, ExportHookFunc, MUIV_TextEditor_ExportHook_EMail);
424 MakeHookWithData(ExportHookNoStyle, ExportHookFunc, MUIV_TextEditor_ExportHook_NoStyle);