hedgewars/uRenderUtils.pas
changeset 10687 2e921409b5b1
parent 10494 0eb97cf4c78e
child 10689 692649e341fc
equal deleted inserted replaced
10686:279dab90a0f8 10687:2e921409b5b1
   302 
   302 
   303         SDL_FreeSurface(finalSurface);
   303         SDL_FreeSurface(finalSurface);
   304         end;
   304         end;
   305 end;
   305 end;
   306 
   306 
       
   307 function GetNextSpeechLine(s: ansistring; ldelim: char; var startFrom: LongInt; out substr: shortstring): boolean;
       
   308 var p, l, m, r: Integer;
       
   309     newl      : boolean;
       
   310     c         : char;
       
   311 begin
       
   312     m:= Length(s);
       
   313 
       
   314     SetLength(substr, m);
       
   315 
       
   316     // number of chars read
       
   317     r:= 0;
       
   318 
       
   319     // number of chars to be written
       
   320     l:= 0;
       
   321 
       
   322     newl:= true;
       
   323 
       
   324     for p:= max(1, startFrom) to m do
       
   325         begin
       
   326         inc(r);
       
   327         c:= s[p];
       
   328 
       
   329         // strip empty lines, spaces and newlines on beginnings of line
       
   330         if (newl or (p = m)) and ((c = ' ') or (c = ldelim)) then
       
   331             continue;
       
   332 
       
   333         newl:= (c = ldelim);
       
   334         if newl then
       
   335             break;
       
   336 
       
   337         inc(l);
       
   338         substr[l]:= c;
       
   339         end;
       
   340 
       
   341     inc(startFrom, r);
       
   342 
       
   343     SetLength(substr, l);
       
   344 
       
   345     GetNextSpeechLine:= (l > 0);
       
   346 end;
   307 
   347 
   308 function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture;
   348 function RenderSpeechBubbleTex(s: ansistring; SpeechType: Longword; font: THWFont): PTexture;
   309 var textWidth, textHeight, x, y, w, h, i, j, pos, prevpos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt;
   349 var textWidth, textHeight, x, y, w, h, i, j, pos, line, numLines, edgeWidth, edgeHeight, cornerWidth, cornerHeight: LongInt;
   310     finalSurface, tmpsurf, rotatedEdge: PSDL_Surface;
   350     finalSurface, tmpsurf, rotatedEdge: PSDL_Surface;
   311     rect: TSDL_Rect;
   351     rect: TSDL_Rect;
   312     {$IFNDEF PAS2C}
   352     {$IFNDEF PAS2C}
   313     chars: set of char = [#9,' ',';',':','?','!',','];
   353     chars: set of char = [#9,' ',';',':','?','!',','];
   314     {$ENDIF}
   354     {$ENDIF}
   360         w:= 0;
   400         w:= 0;
   361         i:= round(Sqrt(length(s)) * 2);
   401         i:= round(Sqrt(length(s)) * 2);
   362         {$IFNDEF PAS2C}
   402         {$IFNDEF PAS2C}
   363         s:= WrapText(s, #1, chars, i);
   403         s:= WrapText(s, #1, chars, i);
   364         {$ENDIF}
   404         {$ENDIF}
   365         pos:= 1; prevpos:= 0; line:= 0;
   405         pos:= 1; line:= 0;
   366     // Find the longest line for the purposes of centring the text.  Font dependant.
   406     // Find the longest line for the purposes of centring the text.  Font dependant.
   367         while pos <= length(s) do
   407         while GetNextSpeechLine(s, #1, pos, substr) do
   368             begin
   408             begin
   369             if (s[pos] = #1) or (pos = length(s)) then
   409             inc(numLines);
   370                 begin
   410             i:= 0; j:= 0;
   371                 inc(numlines);
   411             TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(substr), @i, @j);
   372                 if s[pos] <> #1 then inc(pos);
   412             if i > w then
   373                 while s[prevpos+1] = ' ' do inc(prevpos);
   413                 w:= i;
   374                 substr:= copy(s, prevpos+1, pos-prevpos-1);
       
   375                 i:= 0; j:= 0;
       
   376                 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(substr), @i, @j);
       
   377                 if i > w then
       
   378                     w:= i;
       
   379                 prevpos:= pos;
       
   380                 end;
       
   381             inc(pos);
       
   382             end;
   414             end;
   383         end
   415         end
   384     else numLines := 1;
   416     else numLines := 1;
       
   417 
       
   418     if numLines < 1 then
       
   419         begin
       
   420         s:= '...';
       
   421         numLines:= 1;
       
   422         end;
   385 
   423 
   386     textWidth:=((w-(cornerWidth-edgeWidth)*2) div edgeWidth)*edgeWidth+edgeWidth;
   424     textWidth:=((w-(cornerWidth-edgeWidth)*2) div edgeWidth)*edgeWidth+edgeWidth;
   387     textHeight:=(((numlines * h + 2)-((cornerHeight-edgeWidth)*2)) div edgeWidth)*edgeWidth;
   425     textHeight:=(((numlines * h + 2)-((cornerHeight-edgeWidth)*2)) div edgeWidth)*edgeWidth;
   388 
   426 
   389     textHeight:=max(textHeight,edgeWidth);
   427     textHeight:=max(textHeight,edgeWidth);
   466     rect.h:= textHeight + cornerHeight * 2 - edgeHeight * 2;
   504     rect.h:= textHeight + cornerHeight * 2 - edgeHeight * 2;
   467     i:= rect.w;
   505     i:= rect.w;
   468     j:= rect.h;
   506     j:= rect.h;
   469     SDL_FillRect(finalSurface, @rect, cWhiteColor);
   507     SDL_FillRect(finalSurface, @rect, cWhiteColor);
   470 
   508 
   471     pos:= 1; prevpos:= 0; line:= 0;
   509     pos:= 1; line:= 0;
   472     while pos <= length(s) do
   510     while GetNextSpeechLine(s, #1, pos, substr) do
   473         begin
   511         begin
   474         if (s[pos] = #1) or (pos = length(s)) then
   512         tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(substr), cNearBlackColorChannels);
   475             begin
   513         rect.x:= edgeHeight + 1 + ((i - w) div 2);
   476             if s[pos] <> #1 then
   514         // trying to more evenly position the text, vertically
   477                 inc(pos);
   515         rect.y:= edgeHeight + ((j-(numLines*h)) div 2) + line * h;
   478             while s[prevpos+1] = ' 'do
   516         SDLTry(tmpsurf <> nil, true);
   479                 inc(prevpos);
   517         SDL_UpperBlit(tmpsurf, nil, finalSurface, @rect);
   480             substr:= copy(s, prevpos+1, pos-prevpos-1);
   518         SDL_FreeSurface(tmpsurf);
   481             if Length(substr) <> 0 then
   519         inc(line);
   482                 begin
       
   483                 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(substr), cNearBlackColorChannels);
       
   484                 rect.x:= edgeHeight + 1 + ((i - w) div 2);
       
   485                 // trying to more evenly position the text, vertically
       
   486                 rect.y:= edgeHeight + ((j-(numLines*h)) div 2) + line * h;
       
   487                 SDLTry(tmpsurf <> nil, true);
       
   488                 SDL_UpperBlit(tmpsurf, nil, finalSurface, @rect);
       
   489                 SDL_FreeSurface(tmpsurf);
       
   490                 inc(line);
       
   491                 prevpos:= pos;
       
   492                 end;
       
   493                 end;
       
   494         inc(pos);
       
   495         end;
   520         end;
   496 
   521 
   497     RenderSpeechBubbleTex:= Surface2Tex(finalSurface, true);
   522     RenderSpeechBubbleTex:= Surface2Tex(finalSurface, true);
   498 
   523 
   499     SDL_FreeSurface(rotatedEdge);
   524     SDL_FreeSurface(rotatedEdge);