@@ -266,94 +266,119 @@ static void delCharLeft(utf_32_char *pBuffer, UDWORD *pPos)
266
266
/* Calculate how much of the start of a string can fit into the edit box */
267
267
static void fitStringStart (utf_32_char * pBuffer , UDWORD boxWidth , UWORD * pCount , UWORD * pCharWidth )
268
268
{
269
- UDWORD len ;
270
- UWORD printChars = 0 , pixelWidth = 0 ;
271
- char * utf = NULL ;
272
- char * utf2 = NULL ;
269
+ UDWORD size32 ;
270
+ UWORD pixelWidth = 0 ;
271
+ char * utf = NULL ;
273
272
273
+ size32 = utf32len (pBuffer );
274
274
utf = UTF32toUTF8 (pBuffer , NULL );
275
275
if (!utf )
276
276
{
277
277
debug (LOG_ERROR , "Couldn't convert UTF32 to UTF8?" );
278
278
* pCount = * pCharWidth = 0 ;
279
279
return ;
280
280
}
281
- len = strlen (utf );
282
281
283
282
// We need to calculate the whole string's pixel size.
284
283
// From QuesoGLC's notes: additional processing like kerning creates strings of text whose dimensions are not directly
285
284
// related to the simple juxtaposition of individual glyph metrics. For example, the advance width of "VA" isn't the
286
285
// sum of the advances of "V" and "A" taken separately.
287
286
pixelWidth = iV_GetTextWidth (utf );
287
+ free (utf ); // release the utf buffer
288
288
289
289
// Find the number of characters that will fit in boxWidth
290
290
if (pixelWidth < boxWidth - (WEDB_XGAP * 2 + WEDB_CURSORSIZE ))
291
291
{
292
- * pCharWidth = pixelWidth ; // the actual pixelWidth we use for the string
293
- * pCount = len ; // and the length of said string.
292
+ * pCharWidth = pixelWidth ; // the actual pixelWidth we use for the string
293
+ * pCount = size32 ; // and the length of said string.
294
+
295
+ return ;
294
296
}
295
297
else
296
298
{
297
- utf2 = utf ;
299
+ utf_32_char * tmp ;
300
+ int printChars = 0 ;
301
+
302
+ tmp = malloc ( sizeof (utf_32_char ) * size32 + sizeof (utf_32_char ));
303
+ memcpy (tmp , pBuffer , sizeof (utf_32_char ) * size32 );
304
+ tmp [size32 ] = 0 ;
305
+
306
+ // we must do this, since it is possible to have invalid utf8 when you start removing just 1 byte at a time
298
307
do
299
308
{
300
- pixelWidth = iV_GetTextWidth (utf2 );
309
+ utf = UTF32toUTF8 (tmp , NULL );
310
+ pixelWidth = iV_GetTextWidth (utf );
301
311
printChars ++ ;
302
- utf2 [(len - printChars )] = 0 ; // keep chopping off end until it fits
312
+ free (utf );
313
+ tmp [(size32 - printChars )] = 0 ; // keep chopping off end until it fits
303
314
}
304
- while (pixelWidth > boxWidth - (WEDB_XGAP * 2 + WEDB_CURSORSIZE ) && printChars < len );
315
+ while (pixelWidth > boxWidth - (WEDB_XGAP * 2 + WEDB_CURSORSIZE ) && printChars < size32 );
305
316
317
+ size32 = utf32len (tmp ); // length we ended up with
318
+ free (tmp );
306
319
* pCharWidth = pixelWidth ; // the actual pixelWidth we use for the string
307
- * pCount = len - printChars ; // and the length of the new string.
320
+ * pCount = size32 ; // and the length of the new string.
308
321
}
309
- free (utf ); // release the utf buffer
310
322
}
311
323
312
324
313
325
/* Calculate how much of the end of a string can fit into the edit box */
314
326
static void fitStringEnd (utf_32_char * pBuffer , UDWORD boxWidth , UWORD * pStart , UWORD * pCount , UWORD * pCharWidth )
315
327
{
316
- UDWORD len ;
317
- UWORD printChars = 0 , pixelWidth = 0 ;
328
+ UDWORD olen32 , nlen32 ;
329
+ UWORD pixelWidth = 0 ;
318
330
char * utf = NULL ;
319
- char * utf2 = NULL ;
320
331
332
+ olen32 = utf32len (pBuffer ); // original length
321
333
utf = UTF32toUTF8 (pBuffer , NULL );
322
334
if (!utf )
323
335
{
324
336
debug (LOG_ERROR , "Couldn't convert UTF32 to UTF8?" );
325
337
* pCount = * pStart = * pCharWidth = 0 ;
326
338
return ;
327
339
}
328
- len = strlen (utf );
329
340
330
341
// We need to calculate the whole string's pixel size.
331
342
// From QuesoGLC's notes: additional processing like kerning creates strings of text whose dimensions are not directly
332
343
// related to the simple juxtaposition of individual glyph metrics. For example, the advance width of "VA" isn't the
333
344
// sum of the advances of "V" and "A" taken separately.
334
345
pixelWidth = iV_GetTextWidth (utf );
346
+ free (utf ); // release the utf buffer
335
347
336
348
// Find the number of characters that will fit in boxWidth
337
349
if (pixelWidth < boxWidth - (WEDB_XGAP * 2 + WEDB_CURSORSIZE ))
338
350
{
339
- * pStart = 0 ; // nothing to trim
340
- * pCharWidth = pixelWidth ; // the actual pixelWidth we use for the string
341
- * pCount = len ; // and the length of said string.
351
+ * pStart = 0 ; // nothing to trim
352
+ * pCharWidth = pixelWidth ; // the actual pixelWidth we use for the string
353
+ * pCount = olen32 ; // and the length of said string.
354
+
355
+ return ;
342
356
}
343
357
else
344
358
{
345
- utf2 = utf ;
346
- while (pixelWidth > boxWidth - (WEDB_XGAP * 2 + WEDB_CURSORSIZE ) && printChars < len )
359
+ utf_32_char * tmp = NULL , * utf32buf = NULL ;
360
+ int printChars = 0 ;
361
+
362
+ utf32buf = malloc ( sizeof (utf_32_char ) * olen32 + sizeof (utf_32_char ));
363
+ memcpy (utf32buf , pBuffer , sizeof (utf_32_char ) * olen32 );
364
+ utf32buf [olen32 ] = 0 ;
365
+ tmp = utf32buf ;
366
+
367
+ while (pixelWidth > boxWidth - (WEDB_XGAP * 2 + WEDB_CURSORSIZE ) && printChars < olen32 )
347
368
{
348
- utf2 ++ ; // new string is 1 char shorter [abc] is now [bc]
349
- pixelWidth = iV_GetTextWidth (utf2 );
369
+ tmp ++ ; // new string is 1 char shorter [abc] is now [bc]
370
+ utf = UTF32toUTF8 (tmp , NULL );
371
+ pixelWidth = iV_GetTextWidth (utf );
350
372
printChars ++ ;
373
+ free (utf );
351
374
}
352
- * pStart = len - (len - printChars ); // the starting position of the string to display
375
+
376
+ nlen32 = utf32len (tmp ); // new size of string
377
+ * pStart = printChars ; // the starting position of the string to display
353
378
* pCharWidth = pixelWidth ; // the actual pixelWidth we use for the string
354
- * pCount = len - printChars ; // and the length of the new string.
379
+ * pCount = nlen32 ; // and the length of the new string.
380
+ free (utf32buf );
355
381
}
356
- free (utf ); // release the utf buffer
357
382
}
358
383
359
384
@@ -497,8 +522,7 @@ void editBoxRun(W_EDITBOX *psWidget, W_CONTEXT *psContext)
497
522
delCharRight (pBuffer , & pos );
498
523
499
524
/* Update the printable text */
500
- fitStringStart (pBuffer + printStart , psWidget -> width ,
501
- & printChars , & printWidth );
525
+ fitStringStart (pBuffer + printStart , psWidget -> width , & printChars , & printWidth );
502
526
debug (LOG_INPUT , "EditBox cursor delete" );
503
527
break ;
504
528
case INPBUF_PGUP :
@@ -523,14 +547,12 @@ void editBoxRun(W_EDITBOX *psWidget, W_CONTEXT *psContext)
523
547
else
524
548
{
525
549
printStart -= WEDB_CHARJUMP ;
526
- fitStringStart (pBuffer + printStart , psWidget -> width ,
527
- & printChars , & printWidth );
550
+ fitStringStart (pBuffer + printStart , psWidget -> width , & printChars , & printWidth );
528
551
}
529
552
}
530
553
else
531
554
{
532
- fitStringStart (pBuffer + printStart , psWidget -> width ,
533
- & printChars , & printWidth );
555
+ fitStringStart (pBuffer + printStart , psWidget -> width , & printChars , & printWidth );
534
556
}
535
557
debug (LOG_INPUT , "EditBox cursor backspace" );
536
558
break ;
@@ -563,9 +585,9 @@ void editBoxRun(W_EDITBOX *psWidget, W_CONTEXT *psContext)
563
585
{
564
586
overwriteChar (& pBuffer , & pBufferAllocated , & pos , unicode , psWidget );
565
587
}
566
-
588
+ len = utf32len ( pBuffer );
567
589
/* Update the printable chars */
568
- if (pos == utf32len ( pBuffer ) )
590
+ if (pos == len )
569
591
{
570
592
fitStringEnd (pBuffer , psWidget -> width , & printStart , & printChars , & printWidth );
571
593
}
@@ -578,8 +600,7 @@ void editBoxRun(W_EDITBOX *psWidget, W_CONTEXT *psContext)
578
600
if (printStart >= len )
579
601
{
580
602
printStart = (UWORD )(len - 1 );
581
- fitStringStart (pBuffer + printStart , psWidget -> width ,
582
- & printChars , & printWidth );
603
+ fitStringStart (pBuffer + printStart , psWidget -> width , & printChars , & printWidth );
583
604
}
584
605
}
585
606
}
@@ -666,8 +687,7 @@ void editBoxFocusLost(W_SCREEN* psScreen, W_EDITBOX *psWidget)
666
687
/* Stop editing the widget */
667
688
psWidget -> state = WEDBS_FIXED ;
668
689
psWidget -> printStart = 0 ;
669
- fitStringStart (psWidget -> aText ,psWidget -> width ,
670
- & psWidget -> printChars , & psWidget -> printWidth );
690
+ fitStringStart (psWidget -> aText ,psWidget -> width , & psWidget -> printChars , & psWidget -> printWidth );
671
691
672
692
widgSetReturn (psScreen , (WIDGET * )psWidget );
673
693
@@ -689,7 +709,8 @@ void editBoxHiLite(W_EDITBOX *psWidget)
689
709
return ;
690
710
}
691
711
692
- if (psWidget -> AudioCallback ) {
712
+ if (psWidget -> AudioCallback )
713
+ {
693
714
psWidget -> AudioCallback (psWidget -> HilightAudioID );
694
715
}
695
716
@@ -715,11 +736,13 @@ void editBoxDisplay(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *
715
736
W_EDITBOX * psEdBox ;
716
737
SDWORD x0 ,y0 ,x1 ,y1 , fx ,fy , cx ,cy ;
717
738
enum iV_fonts CurrFontID ;
718
- utf_32_char ch , * pInsPoint , * pPrint ;
739
+
719
740
#if CURSOR_BLINK
720
741
BOOL blink ;
721
742
#endif
722
743
char * utf ;
744
+ utf_32_char * pInsPoint , * UTF32string ;
745
+ int size = 0 ;
723
746
724
747
psEdBox = (W_EDITBOX * )psWidget ;
725
748
CurrFontID = psEdBox -> FontID ;
@@ -729,9 +752,12 @@ void editBoxDisplay(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *
729
752
x1 = x0 + psEdBox -> width ;
730
753
y1 = y0 + psEdBox -> height ;
731
754
732
- if (psEdBox -> pBoxDisplay ) {
755
+ if (psEdBox -> pBoxDisplay )
756
+ {
733
757
psEdBox -> pBoxDisplay ((WIDGET * )psEdBox , xOffset , yOffset , pColours );
734
- } else {
758
+ }
759
+ else
760
+ {
735
761
pie_BoxFill (x0 , y0 , x1 , y1 , pColours [WCOL_BKGRND ]);
736
762
737
763
iV_Line (x0 ,y0 , x1 ,y0 , pColours [WCOL_DARK ]);
@@ -745,41 +771,50 @@ void editBoxDisplay(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *
745
771
iV_SetFont (CurrFontID );
746
772
iV_SetTextColour (pColours [WCOL_TEXT ]);
747
773
748
- fy = y0 + (psEdBox -> height - iV_GetTextLineSize ())/2 - iV_GetTextAboveBase ();
774
+ fy = y0 + (psEdBox -> height - iV_GetTextLineSize ())/2 - iV_GetTextAboveBase ();
749
775
776
+ /* If there is more text than will fit into the box, display the bit with the cursor in it */
777
+ size = utf32len (psEdBox -> aText );
778
+ UTF32string = malloc ( sizeof (utf_32_char ) * size + sizeof (utf_32_char ));
779
+ memcpy (UTF32string , psEdBox -> aText , sizeof (utf_32_char ) * size );
750
780
751
- /* If there is more text than will fit into the box,
752
- display the bit with the cursor in it */
753
- pPrint = psEdBox -> aText + psEdBox -> printStart ;
754
- pInsPoint = pPrint + psEdBox -> printChars ;
755
- ch = * pInsPoint ;
781
+ pInsPoint = UTF32string + psEdBox -> printStart ; // deal with position
782
+ pInsPoint [psEdBox -> printChars ] = 0 ;
783
+
784
+ utf = UTF32toUTF8 (pInsPoint , NULL );
756
785
757
- * pInsPoint = '\0' ;
758
- utf = UTF32toUTF8 (pPrint , NULL );
759
786
#ifdef WZ_OS_MAC
760
787
iV_DrawText (utf , fx , fy + 2 );
761
788
#else
762
789
iV_DrawText (utf , fx , fy );
763
790
#endif
764
791
free (utf );
765
- * pInsPoint = ch ;
792
+ free ( UTF32string ) ;
766
793
767
- /* Display the cursor if editing */
794
+ // Display the cursor if editing
768
795
#if CURSOR_BLINK
769
796
blink = !(((SDL_GetTicks () - psEdBox -> blinkOffset )/WEDB_BLINKRATE ) % 2 );
770
797
if ((psEdBox -> state & WEDBS_MASK ) == WEDBS_INSERT && blink )
771
798
#else
772
799
if ((psEdBox -> state & WEDBS_MASK ) == WEDBS_INSERT )
773
800
#endif
774
801
{
775
- pInsPoint = psEdBox -> aText + psEdBox -> insPos ;
776
- ch = * pInsPoint ;
777
- * pInsPoint = '\0' ;
778
- utf = UTF32toUTF8 (psEdBox -> aText + psEdBox -> printStart , NULL );
802
+ // insert mode
803
+
804
+ utf_32_char * pInsPoint , * UTF32string ;
805
+ int size = 0 ;
806
+
807
+ size = utf32len (psEdBox -> aText );
808
+ UTF32string = malloc ( sizeof (utf_32_char ) * size + sizeof (utf_32_char ));
809
+ memcpy (UTF32string , psEdBox -> aText , sizeof (utf_32_char ) * size );
810
+
811
+ pInsPoint = UTF32string + psEdBox -> insPos ; // deal with position
812
+ * pInsPoint = 0 ;
813
+ utf = UTF32toUTF8 (UTF32string + psEdBox -> printStart , NULL );
779
814
cx = x0 + WEDB_XGAP + iV_GetTextWidth (utf );
780
815
cx += iV_GetTextWidth ("-" );
781
816
free (utf );
782
- * pInsPoint = ch ;
817
+ free ( UTF32string ) ;
783
818
cy = fy ;
784
819
iV_Line (cx , cy + iV_GetTextAboveBase (), cx , cy - iV_GetTextBelowBase (), pColours [WCOL_CURSOR ]);
785
820
}
@@ -789,19 +824,26 @@ void editBoxDisplay(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *
789
824
else if ((psEdBox -> state & WEDBS_MASK ) == WEDBS_OVER )
790
825
#endif
791
826
{
792
- pInsPoint = psEdBox -> aText + psEdBox -> insPos ;
793
- ch = * pInsPoint ;
794
- * pInsPoint = '\0' ;
795
- utf = UTF32toUTF8 (psEdBox -> aText + psEdBox -> printStart , NULL );
827
+ // overwrite mode
828
+ utf_32_char * pInsPoint , * UTF32string ;
829
+ int size = 0 ;
830
+
831
+ size = utf32len (psEdBox -> aText );
832
+ UTF32string = malloc ( sizeof (utf_32_char ) * size + sizeof (utf_32_char ));
833
+ memcpy (UTF32string , psEdBox -> aText , sizeof (utf_32_char ) * size );
834
+
835
+ pInsPoint = UTF32string + psEdBox -> insPos ; // deal with position
836
+ * pInsPoint = 0 ;
837
+ utf = UTF32toUTF8 (UTF32string + psEdBox -> printStart , NULL );
796
838
cx = x0 + WEDB_XGAP + iV_GetTextWidth (utf );
797
839
free (utf );
798
- * pInsPoint = ch ;
799
- cy = fy ;
840
+ free ( UTF32string ) ;
841
+ cy = fy ;
800
842
iV_Line (cx , cy , cx + WEDB_CURSORSIZE , cy , pColours [WCOL_CURSOR ]);
801
843
}
802
844
803
-
804
- if ( psEdBox -> pBoxDisplay == NULL ) {
845
+ if ( psEdBox -> pBoxDisplay == NULL )
846
+ {
805
847
if (psEdBox -> state & WEDBS_HILITE )
806
848
{
807
849
/* Display the button hilite */
0 commit comments