fixed drawing text from file that contains DOS style CR/LF line endings
[rocksndiamonds.git] / src / libgame / text.c
index 02a23c3d43b02a053ffabf7fced633d441531de4..ce855daf9604496ddc89287ae8cade95676f37b7 100644 (file)
@@ -4,7 +4,7 @@
 // (c) 1995-2014 by Artsoft Entertainment
 //                         Holger Schemel
 //                 info@artsoft.org
-//                 http://www.artsoft.org/
+//                 https://www.artsoft.org/
 // ----------------------------------------------------------------------------
 // text.c
 // ============================================================================
@@ -136,7 +136,7 @@ int maxWordLengthInRequestString(char *text)
 // simple text drawing functions
 // ============================================================================
 
-void DrawInitText(char *text, int ypos, int font_nr)
+static void DrawInitTextExt(char *text, int ypos, int font_nr, boolean update)
 {
   LimitScreenUpdates(TRUE);
 
@@ -152,13 +152,29 @@ void DrawInitText(char *text, int ypos, int font_nr)
     int width = video.width;
     int height = getFontHeight(font_nr);
 
-    ClearRectangle(drawto, 0, y, width, height);
-    DrawTextExt(drawto, x, y, text, font_nr, BLIT_OPAQUE);
+    ClearRectangleOnBackground(drawto, 0, y, width, height);
+    DrawTextExt(drawto, x, y, text, font_nr, BLIT_MASKED);
 
-    BlitBitmap(drawto, window, 0, 0, video.width, video.height, 0, 0);
+    if (update)
+      BlitBitmap(drawto, window, 0, 0, video.width, video.height, 0, 0);
   }
 }
 
+void DrawInitText(char *text, int ypos, int font_nr)
+{
+  DrawInitTextExt(text, ypos, font_nr, FALSE);
+}
+
+void DrawInitTextHead(char *text)
+{
+  DrawInitTextExt(text, 120, FC_GREEN, FALSE);
+}
+
+void DrawInitTextItem(char *text)
+{
+  DrawInitTextExt(text, 150, FC_YELLOW, TRUE);
+}
+
 void DrawTextF(int x, int y, int font_nr, char *format, ...)
 {
   char buffer[MAX_OUTPUT_LINESIZE + 1];
@@ -169,7 +185,7 @@ void DrawTextF(int x, int y, int font_nr, char *format, ...)
   va_end(ap);
 
   if (strlen(buffer) > MAX_OUTPUT_LINESIZE)
-    Error(ERR_EXIT, "string too long in DrawTextF() -- aborting");
+    Fail("string too long in DrawTextF() -- aborting");
 
   DrawText(gfx.sx + x, gfx.sy + y, buffer, font_nr);
 }
@@ -184,7 +200,7 @@ void DrawTextFCentered(int y, int font_nr, char *format, ...)
   va_end(ap);
 
   if (strlen(buffer) > MAX_OUTPUT_LINESIZE)
-    Error(ERR_EXIT, "string too long in DrawTextFCentered() -- aborting");
+    Fail("string too long in DrawTextFCentered() -- aborting");
 
   DrawText(gfx.sx + (gfx.sxsize - getTextWidth(buffer, font_nr)) / 2,
           gfx.sy + y, buffer, font_nr);
@@ -207,12 +223,6 @@ void DrawTextSAligned(int x, int y, char *text, int font_nr, int align)
           gfx.sy + y, text, font_nr);
 }
 
-void DrawTextAligned(int x, int y, char *text, int font_nr, int align)
-{
-  DrawText(ALIGNED_XPOS(x, getTextWidth(text, font_nr), align),
-          y, text, font_nr);
-}
-
 void DrawText(int x, int y, char *text, int font_nr)
 {
   int mask_mode = BLIT_OPAQUE;
@@ -341,11 +351,24 @@ char *GetTextBufferFromFile(char *filename, int max_lines)
   while (!checkEndOfFile(file) && num_lines < max_lines)
   {
     char line[MAX_LINE_LEN];
+    char *line_ptr;
+    int line_len;
 
     // read next line of input file
     if (!getStringFromFile(file, line, MAX_LINE_LEN))
       break;
 
+    line_len = strlen(line);
+
+    // cut trailing line break (this can be newline and/or carriage return)
+    for (line_ptr = &line[line_len]; line_ptr >= line; line_ptr--)
+      if ((*line_ptr == '\n' || *line_ptr == '\r') && *(line_ptr + 1) == '\0')
+       *line_ptr = '\0';
+
+    // re-add newline (so the result is terminated by newline, but not CR/LF)
+    if (strlen(line) != line_len)
+      strcat(line, "\n");
+
     buffer = checked_realloc(buffer, strlen(buffer) + strlen(line) + 1);
 
     strcat(buffer, line);
@@ -355,6 +378,15 @@ char *GetTextBufferFromFile(char *filename, int max_lines)
 
   closeFile(file);
 
+  if (getTextEncoding(buffer) == TEXT_ENCODING_UTF_8)
+  {
+    char *body_latin1 = getLatin1FromUTF8(buffer);
+
+    checked_free(buffer);
+
+    buffer = body_latin1;
+  }
+
   return buffer;
 }
 
@@ -481,10 +513,11 @@ static void DrawTextBuffer_Flush(int x, int y, char *buffer, int font_nr,
     DrawText(xx, yy, buffer, font_nr);
 }
 
-int DrawTextBuffer(int x, int y, char *text_buffer, int font_nr,
-                  int line_length, int cut_length, int max_lines,
-                  int line_spacing, int mask_mode, boolean autowrap,
-                  boolean centered, boolean parse_comments)
+static int DrawTextBufferExt(int x, int y, char *text_buffer, int font_nr,
+                            int line_length, int cut_length, int max_lines,
+                            int line_spacing, int mask_mode, boolean autowrap,
+                            boolean centered, boolean parse_comments,
+                            boolean is_text_area)
 {
   char buffer[line_length + 1];
   int buffer_len;
@@ -516,8 +549,16 @@ int DrawTextBuffer(int x, int y, char *text_buffer, int font_nr,
 
     // copy next line from text buffer to line buffer (nearly fgets() style)
     for (i = 0; i < num_line_chars && *text_buffer; i++)
+    {
       if ((line[i] = *text_buffer++) == '\n')
+      {
+       // in text areas, 'line_length' sized lines cause additional empty line
+       if (i == line_length && is_text_area)
+         text_buffer--;
+
        break;
+      }
+    }
     line[i] = '\0';
 
     // prevent 'num_line_chars' sized lines to cause additional empty line
@@ -630,6 +671,39 @@ int DrawTextBuffer(int x, int y, char *text_buffer, int font_nr,
   return current_line;
 }
 
+int DrawTextArea(int x, int y, char *text_buffer, int font_nr,
+                int line_length, int cut_length, int max_lines,
+                int line_spacing, int mask_mode, boolean autowrap,
+                boolean centered, boolean parse_comments)
+{
+  return DrawTextBufferExt(x, y, text_buffer, font_nr,
+                          line_length, cut_length, max_lines,
+                          line_spacing, mask_mode, autowrap,
+                          centered, parse_comments, TRUE);
+}
+
+int DrawTextBuffer(int x, int y, char *text_buffer, int font_nr,
+                  int line_length, int cut_length, int max_lines,
+                  int line_spacing, int mask_mode, boolean autowrap,
+                  boolean centered, boolean parse_comments)
+{
+  return DrawTextBufferExt(x, y, text_buffer, font_nr,
+                          line_length, cut_length, max_lines,
+                          line_spacing, mask_mode, autowrap,
+                          centered, parse_comments, FALSE);
+}
+
+int DrawTextBufferS(int x, int y, char *text_buffer, int font_nr,
+                   int line_length, int cut_length, int max_lines,
+                   int line_spacing, int mask_mode, boolean autowrap,
+                   boolean centered, boolean parse_comments)
+{
+  return DrawTextBuffer(gfx.sx + x, gfx.sy + y, text_buffer, font_nr,
+                       line_length, cut_length, max_lines,
+                       line_spacing, mask_mode, autowrap,
+                       centered, parse_comments);
+}
+
 int DrawTextBufferVA(int x, int y, char *format, va_list ap, int font_nr,
                     int line_length, int cut_length, int max_lines,
                     int line_spacing, int mask_mode, boolean autowrap,
@@ -639,7 +713,7 @@ int DrawTextBufferVA(int x, int y, char *format, va_list ap, int font_nr,
   int text_length = vsnprintf(text_buffer, MAX_OUTPUT_LINESIZE, format, ap);
 
   if (text_length >= MAX_OUTPUT_LINESIZE)
-    Error(ERR_WARN, "string too long in DrawTextBufferVA() -- truncated");
+    Warn("string too long in DrawTextBufferVA() -- truncated");
 
   int num_lines_printed = DrawTextBuffer(x, y, text_buffer, font_nr,
                                         line_length, cut_length, max_lines,