root/maint/gnulib/lib/unilbrk/u32-width-linebreaks.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. u32_width_linebreaks

   1 /* Line breaking of UTF-32 strings.
   2    Copyright (C) 2001-2003, 2006-2021 Free Software Foundation, Inc.
   3    Written by Bruno Haible <bruno@clisp.org>, 2001.
   4 
   5    This file is free software.
   6    It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+".
   7    You can redistribute it and/or modify it under either
   8      - the terms of the GNU Lesser General Public License as published
   9        by the Free Software Foundation; either version 3, or (at your
  10        option) any later version, or
  11      - the terms of the GNU General Public License as published by the
  12        Free Software Foundation; either version 2, or (at your option)
  13        any later version, or
  14      - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+".
  15 
  16    This file is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19    Lesser General Public License and the GNU General Public License
  20    for more details.
  21 
  22    You should have received a copy of the GNU Lesser General Public
  23    License and of the GNU General Public License along with this
  24    program.  If not, see <https://www.gnu.org/licenses/>.  */
  25 
  26 #include <config.h>
  27 
  28 /* Specification.  */
  29 #include "unilbrk.h"
  30 
  31 #include "uniwidth.h"
  32 
  33 int
  34 u32_width_linebreaks (const uint32_t *s, size_t n,
     /* [previous][next][first][last][top][bottom][index][help] */
  35                       int width, int start_column, int at_end_columns,
  36                       const char *o, const char *encoding,
  37                       char *p)
  38 {
  39   const uint32_t *s_end;
  40   char *last_p;
  41   int last_column;
  42   int piece_width;
  43 
  44   u32_possible_linebreaks (s, n, encoding, p);
  45 
  46   s_end = s + n;
  47   last_p = NULL;
  48   last_column = start_column;
  49   piece_width = 0;
  50   while (s < s_end)
  51     {
  52       ucs4_t uc = *s;
  53 
  54       /* Respect the override.  */
  55       if (o != NULL && *o != UC_BREAK_UNDEFINED)
  56         *p = *o;
  57 
  58       if (*p == UC_BREAK_POSSIBLE || *p == UC_BREAK_MANDATORY)
  59         {
  60           /* An atomic piece of text ends here.  */
  61           if (last_p != NULL && last_column + piece_width > width)
  62             {
  63               /* Insert a line break.  */
  64               *last_p = UC_BREAK_POSSIBLE;
  65               last_column = 0;
  66             }
  67         }
  68 
  69       if (*p == UC_BREAK_MANDATORY)
  70         {
  71           /* uc is a line break character.  */
  72           /* Start a new piece at column 0.  */
  73           last_p = NULL;
  74           last_column = 0;
  75           piece_width = 0;
  76         }
  77       else
  78         {
  79           /* uc is not a line break character.  */
  80           int w;
  81 
  82           if (*p == UC_BREAK_POSSIBLE)
  83             {
  84               /* Start a new piece.  */
  85               last_p = p;
  86               last_column += piece_width;
  87               piece_width = 0;
  88               /* No line break for the moment, may be turned into
  89                  UC_BREAK_POSSIBLE later, via last_p. */
  90             }
  91 
  92           *p = UC_BREAK_PROHIBITED;
  93 
  94           w = uc_width (uc, encoding);
  95           if (w >= 0) /* ignore control characters in the string */
  96             piece_width += w;
  97         }
  98 
  99       s++;
 100       p++;
 101       if (o != NULL)
 102         o++;
 103     }
 104 
 105   /* The last atomic piece of text ends here.  */
 106   if (last_p != NULL && last_column + piece_width + at_end_columns > width)
 107     {
 108       /* Insert a line break.  */
 109       *last_p = UC_BREAK_POSSIBLE;
 110       last_column = 0;
 111     }
 112 
 113   return last_column + piece_width;
 114 }

/* [previous][next][first][last][top][bottom][index][help] */