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

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

DEFINITIONS

This source file includes following definitions.
  1. u16_width_linebreaks

   1 /* Line breaking of UTF-16 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 "unistr.h"
  32 #include "uniwidth.h"
  33 
  34 int
  35 u16_width_linebreaks (const uint16_t *s, size_t n,
     /* [previous][next][first][last][top][bottom][index][help] */
  36                       int width, int start_column, int at_end_columns,
  37                       const char *o, const char *encoding,
  38                       char *p)
  39 {
  40   const uint16_t *s_end;
  41   char *last_p;
  42   int last_column;
  43   int piece_width;
  44 
  45   u16_possible_linebreaks (s, n, encoding, p);
  46 
  47   s_end = s + n;
  48   last_p = NULL;
  49   last_column = start_column;
  50   piece_width = 0;
  51   while (s < s_end)
  52     {
  53       ucs4_t uc;
  54       int count = u16_mbtouc_unsafe (&uc, s, s_end - s);
  55 
  56       /* Respect the override.  */
  57       if (o != NULL && *o != UC_BREAK_UNDEFINED)
  58         *p = *o;
  59 
  60       if (*p == UC_BREAK_POSSIBLE || *p == UC_BREAK_MANDATORY)
  61         {
  62           /* An atomic piece of text ends here.  */
  63           if (last_p != NULL && last_column + piece_width > width)
  64             {
  65               /* Insert a line break.  */
  66               *last_p = UC_BREAK_POSSIBLE;
  67               last_column = 0;
  68             }
  69         }
  70 
  71       if (*p == UC_BREAK_MANDATORY)
  72         {
  73           /* uc is a line break character.  */
  74           /* Start a new piece at column 0.  */
  75           last_p = NULL;
  76           last_column = 0;
  77           piece_width = 0;
  78         }
  79       else
  80         {
  81           /* uc is not a line break character.  */
  82           int w;
  83 
  84           if (*p == UC_BREAK_POSSIBLE)
  85             {
  86               /* Start a new piece.  */
  87               last_p = p;
  88               last_column += piece_width;
  89               piece_width = 0;
  90               /* No line break for the moment, may be turned into
  91                  UC_BREAK_POSSIBLE later, via last_p. */
  92             }
  93 
  94           *p = UC_BREAK_PROHIBITED;
  95 
  96           w = uc_width (uc, encoding);
  97           if (w >= 0) /* ignore control characters in the string */
  98             piece_width += w;
  99         }
 100 
 101       s += count;
 102       p += count;
 103       if (o != NULL)
 104         o += count;
 105     }
 106 
 107   /* The last atomic piece of text ends here.  */
 108   if (last_p != NULL && last_column + piece_width + at_end_columns > width)
 109     {
 110       /* Insert a line break.  */
 111       *last_p = UC_BREAK_POSSIBLE;
 112       last_column = 0;
 113     }
 114 
 115   return last_column + piece_width;
 116 }

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