2019-10-08 04:37:19 +02:00
|
|
|
|
/***********************************************************************
|
|
|
|
|
* fterm_functions.cpp - FTerm helper functions *
|
|
|
|
|
* *
|
|
|
|
|
* This file is part of the Final Cut widget toolkit *
|
|
|
|
|
* *
|
2020-01-03 01:33:18 +01:00
|
|
|
|
* Copyright 2019-2020 Markus Gans *
|
2019-10-08 04:37:19 +02:00
|
|
|
|
* *
|
|
|
|
|
* The Final Cut is free software; you can redistribute it and/or *
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License *
|
|
|
|
|
* as published by the Free Software Foundation; either version 3 of *
|
|
|
|
|
* the License, or (at your option) any later version. *
|
|
|
|
|
* *
|
|
|
|
|
* The Final Cut is distributed in the hope that it will be useful, *
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
|
* GNU Lesser General Public License for more details. *
|
|
|
|
|
* *
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
|
|
|
* License along with this program. If not, see *
|
|
|
|
|
* <http://www.gnu.org/licenses/>. *
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
2019-10-14 01:44:24 +02:00
|
|
|
|
#if defined(__CYGWIN__)
|
|
|
|
|
#include "final/fconfig.h" // includes _GNU_SOURCE for wcwidth()
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
|
#include "final/fcharmap.h"
|
|
|
|
|
#include "final/fterm.h"
|
|
|
|
|
#include "final/ftermbuffer.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace finalcut
|
|
|
|
|
{
|
|
|
|
|
|
2020-01-03 01:33:18 +01:00
|
|
|
|
// Enumeration
|
|
|
|
|
enum fullWidthSupport
|
|
|
|
|
{
|
|
|
|
|
unknown_fullwidth_support = -1,
|
|
|
|
|
supports_fullwidth = 0,
|
|
|
|
|
no_fullwidth_support = 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// global state
|
|
|
|
|
static fullWidthSupport has_fullwidth_support = unknown_fullwidth_support;
|
|
|
|
|
|
2019-10-17 01:13:18 +02:00
|
|
|
|
// Function prototypes
|
|
|
|
|
bool hasAmbiguousWidth (wchar_t);
|
|
|
|
|
|
|
|
|
|
// Data array
|
|
|
|
|
const wchar_t ambiguous_width_list[] =
|
|
|
|
|
{
|
|
|
|
|
0x00a1, 0x00a4, 0x00a7, 0x00a8, 0x00aa, 0x00ad, 0x00ae, 0x00b0,
|
|
|
|
|
0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b6, 0x00b7, 0x00b8, 0x00b9,
|
|
|
|
|
0x00ba, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00c6, 0x00d0, 0x00d7,
|
|
|
|
|
0x00d8, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e6, 0x00e8, 0x00e9,
|
|
|
|
|
0x00ea, 0x00ec, 0x00ed, 0x00f0, 0x00f2, 0x00f3, 0x00f7, 0x00f8,
|
|
|
|
|
0x00f9, 0x00fa, 0x00fc, 0x00fe, 0x0101, 0x0111, 0x0113, 0x011b,
|
|
|
|
|
0x0126, 0x0127, 0x012b, 0x0131, 0x0132, 0x0133, 0x0138, 0x013f,
|
|
|
|
|
0x0140, 0x0141, 0x0142, 0x0144, 0x0148, 0x0149, 0x014a, 0x014b,
|
|
|
|
|
0x014d, 0x0152, 0x0153, 0x0166, 0x0167, 0x016b, 0x01ce, 0x01d0,
|
|
|
|
|
0x01d2, 0x01d4, 0x01d6, 0x01d8, 0x01da, 0x01dc, 0x0251, 0x0261,
|
|
|
|
|
0x02c4, 0x02c7, 0x02c9, 0x02ca, 0x02cb, 0x02cd, 0x02d0, 0x02d8,
|
|
|
|
|
0x02d9, 0x02da, 0x02db, 0x02dd, 0x02df, 0x0300, 0x0301, 0x0302,
|
|
|
|
|
0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a,
|
|
|
|
|
0x030b, 0x030c, 0x030d, 0x030f, 0x0310, 0x0311, 0x0312, 0x0313,
|
|
|
|
|
0x0314, 0x0315, 0x0316, 0x0317, 0x0318, 0x0319, 0x031a, 0x031b,
|
|
|
|
|
0x031c, 0x031d, 0x031e, 0x031f, 0x0320, 0x0321, 0x0322, 0x0323,
|
|
|
|
|
0x0324, 0x0325, 0x0326, 0x0327, 0x0328, 0x0329, 0x032a, 0x032b,
|
|
|
|
|
0x032c, 0x032d, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333,
|
|
|
|
|
0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033a, 0x033b,
|
|
|
|
|
0x033c, 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343,
|
|
|
|
|
0x0344, 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b,
|
|
|
|
|
0x034c, 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353,
|
|
|
|
|
0x0354, 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b,
|
|
|
|
|
0x035c, 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363,
|
|
|
|
|
0x0364, 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b,
|
|
|
|
|
0x036c, 0x036d, 0x036e, 0x036f, 0x0391, 0x0392, 0x0393, 0x0394,
|
|
|
|
|
0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c,
|
|
|
|
|
0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5,
|
|
|
|
|
0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, 0x03b3, 0x03b4,
|
|
|
|
|
0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc,
|
|
|
|
|
0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5,
|
|
|
|
|
0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x0401, 0x0410, 0x0411, 0x0412,
|
|
|
|
|
0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a,
|
|
|
|
|
0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x0420, 0x0421, 0x0422,
|
|
|
|
|
0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a,
|
|
|
|
|
0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431, 0x0432,
|
|
|
|
|
0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a,
|
|
|
|
|
0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442,
|
|
|
|
|
0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a,
|
|
|
|
|
0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0451, 0x2010, 0x2013,
|
|
|
|
|
0x2014, 0x2015, 0x2016, 0x2018, 0x2019, 0x201c, 0x201d, 0x2020,
|
|
|
|
|
0x2021, 0x2022, 0x2024, 0x2025, 0x2026, 0x2027, 0x2030, 0x2032,
|
|
|
|
|
0x2033, 0x2035, 0x203b, 0x203e, 0x2074, 0x207f, 0x2081, 0x2082,
|
|
|
|
|
0x2083, 0x2084, 0x20ac, 0x2103, 0x2105, 0x2109, 0x2113, 0x2116,
|
|
|
|
|
0x2121, 0x2122, 0x2126, 0x212b, 0x2153, 0x2154, 0x215b, 0x215c,
|
|
|
|
|
0x215d, 0x215e, 0x2160, 0x2162, 0x2162, 0x2163, 0x2164, 0x2165,
|
|
|
|
|
0x2166, 0x2167, 0x2168, 0x2169, 0x216a, 0x216b, 0x2170, 0x2171,
|
|
|
|
|
0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179,
|
|
|
|
|
0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197,
|
|
|
|
|
0x2198, 0x2199, 0x21b8, 0x21b9, 0x21d2, 0x21d4, 0x21e7, 0x2200,
|
|
|
|
|
0x2202, 0x2203, 0x2207, 0x2208, 0x220b, 0x220f, 0x2211, 0x2215,
|
|
|
|
|
0x221a, 0x221d, 0x221e, 0x221f, 0x2220, 0x2223, 0x2225, 0x2227,
|
|
|
|
|
0x2228, 0x2229, 0x222a, 0x222b, 0x222c, 0x222e, 0x2234, 0x2235,
|
|
|
|
|
0x2236, 0x2237, 0x223c, 0x223d, 0x2248, 0x224c, 0x2252, 0x2260,
|
|
|
|
|
0x2261, 0x2264, 0x2265, 0x2266, 0x2267, 0x226a, 0x226b, 0x226e,
|
|
|
|
|
0x226f, 0x2282, 0x2283, 0x2286, 0x2287, 0x2295, 0x2299, 0x22a5,
|
|
|
|
|
0x22bf, 0x2312, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465,
|
|
|
|
|
0x2466, 0x2467, 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d,
|
|
|
|
|
0x246e, 0x246f, 0x2470, 0x2471, 0x2472, 0x2473, 0x2474, 0x2475,
|
|
|
|
|
0x2476, 0x2477, 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d,
|
|
|
|
|
0x247e, 0x247f, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485,
|
|
|
|
|
0x2486, 0x2487, 0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d,
|
|
|
|
|
0x248e, 0x248f, 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495,
|
|
|
|
|
0x2496, 0x2497, 0x2498, 0x2499, 0x249a, 0x249b, 0x249c, 0x249d,
|
|
|
|
|
0x249e, 0x249f, 0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5,
|
|
|
|
|
0x24a6, 0x24a7, 0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad,
|
|
|
|
|
0x24ae, 0x24af, 0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5,
|
|
|
|
|
0x24b6, 0x24b7, 0x24b8, 0x24b9, 0x24ba, 0x24bb, 0x24bc, 0x24bd,
|
|
|
|
|
0x24be, 0x24bf, 0x24c0, 0x24c1, 0x24c2, 0x24c3, 0x24c4, 0x24c5,
|
|
|
|
|
0x24c6, 0x24c7, 0x24c8, 0x24c9, 0x24ca, 0x24cb, 0x24cc, 0x24cd,
|
|
|
|
|
0x24ce, 0x24cf, 0x24d0, 0x24d1, 0x24d2, 0x24d3, 0x24d4, 0x24d5,
|
|
|
|
|
0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da, 0x24db, 0x24dc, 0x24dd,
|
|
|
|
|
0x24de, 0x24df, 0x24e0, 0x24e1, 0x24e2, 0x24e3, 0x24e4, 0x24e5,
|
|
|
|
|
0x24e6, 0x24e7, 0x24e8, 0x24e9, 0x24eb, 0x24ec, 0x24ed, 0x24ee,
|
|
|
|
|
0x24ef, 0x24f0, 0x24f1, 0x24f2, 0x24f3, 0x24f4, 0x24f5, 0x24f6,
|
|
|
|
|
0x24f7, 0x24f8, 0x24f9, 0x24fa, 0x24fb, 0x24fc, 0x24fd, 0x24fe,
|
|
|
|
|
0x2500, 0x2501, 0x2502, 0x2503, 0x2504, 0x2505, 0x2506, 0x2507,
|
|
|
|
|
0x2508, 0x2509, 0x250a, 0x250b, 0x250c, 0x250d, 0x250e, 0x250f,
|
|
|
|
|
0x2510, 0x2511, 0x2512, 0x2513, 0x2514, 0x2515, 0x2516, 0x2517,
|
|
|
|
|
0x2518, 0x2519, 0x251a, 0x251b, 0x251c, 0x251d, 0x251e, 0x251f,
|
|
|
|
|
0x2520, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527,
|
|
|
|
|
0x2528, 0x2529, 0x252a, 0x252b, 0x252c, 0x252d, 0x252e, 0x252f,
|
|
|
|
|
0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537,
|
|
|
|
|
0x2538, 0x2539, 0x253a, 0x253b, 0x253c, 0x253d, 0x253e, 0x253f,
|
|
|
|
|
0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547,
|
|
|
|
|
0x2548, 0x2549, 0x254a, 0x254b, 0x2550, 0x2551, 0x2552, 0x2553,
|
|
|
|
|
0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, 0x255b,
|
|
|
|
|
0x255c, 0x255d, 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, 0x2563,
|
|
|
|
|
0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b,
|
|
|
|
|
0x256c, 0x256d, 0x256e, 0x256f, 0x2570, 0x2571, 0x2572, 0x2573,
|
|
|
|
|
0x2580, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587,
|
|
|
|
|
0x2588, 0x2589, 0x258a, 0x258b, 0x258c, 0x258d, 0x258e, 0x258f,
|
|
|
|
|
0x2590, 0x2592, 0x2593, 0x2594, 0x2595, 0x25a0, 0x25a1, 0x25a3,
|
|
|
|
|
0x25a4, 0x25a5, 0x25a6, 0x25a7, 0x25a8, 0x25a9, 0x25ac, 0x25ae,
|
|
|
|
|
0x25b2, 0x25b3, 0x25b6, 0x25b7, 0x25ba, 0x25bc, 0x25bd, 0x25c0,
|
|
|
|
|
0x25c1, 0x25c4, 0x25c6, 0x25c7, 0x25c8, 0x25cb, 0x25ce, 0x25cf,
|
|
|
|
|
0x25d0, 0x25d1, 0x25d8, 0x25d9, 0x25e2, 0x25e3, 0x25e4, 0x25e5,
|
|
|
|
|
0x25ef, 0x2605, 0x2606, 0x2609, 0x260e, 0x260f, 0x2614, 0x2615,
|
|
|
|
|
0x261c, 0x261e, 0x2640, 0x2642, 0x2660, 0x2661, 0x2663, 0x2664,
|
|
|
|
|
0x2665, 0x2667, 0x2668, 0x2669, 0x266a, 0x266c, 0x266d, 0x266f,
|
|
|
|
|
0x273d, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c,
|
|
|
|
|
0x277d, 0x277e, 0x277f, 0xfe00, 0xfe01, 0xfe02, 0xfe03, 0xfe04,
|
|
|
|
|
0xfe05, 0xfe07, 0xfe09, 0xfe0a, 0xfe0b, 0xfe0c, 0xfe0d, 0xfe0e,
|
|
|
|
|
0xfe0f, 0xfffd
|
|
|
|
|
#if !defined(__CYGWIN__)
|
|
|
|
|
, 0xe0100, 0xe0101, 0xe0102, 0xe0103, 0xe0104, 0xe0105, 0xe0106,
|
|
|
|
|
0xe0107, 0xe0108, 0xe0109, 0xe010a, 0xe01ef
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
2019-11-16 15:16:44 +01:00
|
|
|
|
const wchar_t reverse_newfont_list[] =
|
|
|
|
|
{
|
|
|
|
|
fc::NF_rev_left_arrow2,
|
|
|
|
|
fc::NF_rev_right_arrow2,
|
|
|
|
|
fc::NF_rev_border_corner_upper_right,
|
|
|
|
|
fc::NF_rev_border_line_right,
|
|
|
|
|
fc::NF_rev_border_line_vertical_left,
|
|
|
|
|
fc::NF_rev_border_corner_lower_right,
|
|
|
|
|
fc::NF_rev_up_arrow2,
|
|
|
|
|
fc::NF_rev_down_arrow2,
|
|
|
|
|
fc::NF_rev_up_arrow1,
|
|
|
|
|
fc::NF_rev_down_arrow1,
|
|
|
|
|
fc::NF_rev_left_arrow1,
|
|
|
|
|
fc::NF_rev_right_arrow1,
|
|
|
|
|
fc::NF_rev_menu_button1,
|
|
|
|
|
fc::NF_rev_menu_button2,
|
|
|
|
|
fc::NF_rev_up_pointing_triangle1,
|
|
|
|
|
fc::NF_rev_down_pointing_triangle1,
|
|
|
|
|
fc::NF_rev_up_pointing_triangle2,
|
|
|
|
|
fc::NF_rev_down_pointing_triangle2,
|
|
|
|
|
fc::NF_rev_menu_button3,
|
|
|
|
|
fc::NF_rev_border_line_right_and_left
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-17 01:13:18 +02:00
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
|
// FTerm non-member functions
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
uInt env2uint (const char* env)
|
|
|
|
|
{
|
|
|
|
|
FString str(getenv(env));
|
|
|
|
|
|
|
|
|
|
if ( str.isEmpty() )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return str.toUInt();
|
|
|
|
|
}
|
|
|
|
|
catch (const std::exception&)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-14 01:44:24 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
2019-10-17 01:13:18 +02:00
|
|
|
|
inline bool hasAmbiguousWidth (wchar_t wchar)
|
2019-10-14 01:44:24 +02:00
|
|
|
|
{
|
|
|
|
|
const auto& begin = std::begin(ambiguous_width_list);
|
|
|
|
|
const auto& end = std::end(ambiguous_width_list);
|
|
|
|
|
|
|
|
|
|
if ( std::find(begin, end, wchar) != end ) // found
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-16 15:16:44 +01:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool isReverseNewFontchar (wchar_t wchar)
|
|
|
|
|
{
|
|
|
|
|
const auto& begin = std::begin(reverse_newfont_list);
|
|
|
|
|
const auto& end = std::end(reverse_newfont_list);
|
|
|
|
|
|
|
|
|
|
if ( std::find(begin, end, wchar) != end ) // found
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-03 01:33:18 +01:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
bool hasFullWidthSupports()
|
|
|
|
|
{
|
|
|
|
|
// Checks if the terminal has full-width character support
|
|
|
|
|
|
|
|
|
|
if ( has_fullwidth_support == unknown_fullwidth_support )
|
|
|
|
|
{
|
|
|
|
|
if ( FTerm::isCygwinTerminal()
|
|
|
|
|
|| FTerm::isTeraTerm()
|
|
|
|
|
|| FTerm::isRxvtTerminal()
|
|
|
|
|
|| FTerm::isFreeBSDTerm()
|
|
|
|
|
|| FTerm::isNetBSDTerm()
|
|
|
|
|
|| FTerm::isOpenBSDTerm()
|
|
|
|
|
|| FTerm::isSunTerminal()
|
|
|
|
|
|| FTerm::isAnsiTerminal() )
|
|
|
|
|
has_fullwidth_support = no_fullwidth_support;
|
|
|
|
|
else
|
|
|
|
|
has_fullwidth_support = supports_fullwidth;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ( has_fullwidth_support == supports_fullwidth) ? true : false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
wchar_t cp437_to_unicode (uChar c)
|
|
|
|
|
{
|
|
|
|
|
constexpr std::size_t CP437 = 0;
|
|
|
|
|
constexpr std::size_t UNICODE = 1;
|
|
|
|
|
wchar_t ucs = c;
|
|
|
|
|
|
|
|
|
|
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
|
|
|
|
|
{
|
|
|
|
|
if ( fc::cp437_ucs[i][CP437] == c ) // found
|
|
|
|
|
{
|
|
|
|
|
ucs = fc::cp437_ucs[i][UNICODE];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ucs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
uChar unicode_to_cp437 (wchar_t ucs)
|
|
|
|
|
{
|
|
|
|
|
constexpr std::size_t CP437 = 0;
|
|
|
|
|
constexpr std::size_t UNICODE = 1;
|
|
|
|
|
uChar c{'?'};
|
|
|
|
|
|
|
|
|
|
for (std::size_t i{0}; i <= fc::lastCP437Item; i++)
|
|
|
|
|
{
|
|
|
|
|
if ( fc::cp437_ucs[i][UNICODE] == ucs ) // found
|
|
|
|
|
{
|
|
|
|
|
c = uChar(fc::cp437_ucs[i][CP437]);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FString getFullWidth (const FString& str)
|
|
|
|
|
{
|
|
|
|
|
// Converts half-width to full-width characters
|
|
|
|
|
|
|
|
|
|
FString s(str);
|
|
|
|
|
constexpr std::size_t HALF = 0;
|
|
|
|
|
constexpr std::size_t FULL = 1;
|
|
|
|
|
|
|
|
|
|
for (auto&& c : s)
|
|
|
|
|
{
|
|
|
|
|
if ( c > L'\x20' && c < L'\x7f' ) // half-width ASCII
|
|
|
|
|
{
|
|
|
|
|
c += 0xfee0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (std::size_t i{0}; i <= fc::lastHalfWidthItem; i++)
|
|
|
|
|
{
|
|
|
|
|
if ( fc::halfWidth_fullWidth[i][HALF] == c ) // found
|
|
|
|
|
c = fc::halfWidth_fullWidth[i][FULL];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FString getHalfWidth (const FString& str)
|
|
|
|
|
{
|
|
|
|
|
// Converts full-width to half-width characters
|
|
|
|
|
|
|
|
|
|
FString s(str);
|
|
|
|
|
constexpr std::size_t HALF = 0;
|
|
|
|
|
constexpr std::size_t FULL = 1;
|
|
|
|
|
|
|
|
|
|
for (auto&& c : s)
|
|
|
|
|
{
|
|
|
|
|
if ( c > L'\xff00' && c < L'\xff5f' ) // full-width ASCII
|
|
|
|
|
{
|
|
|
|
|
c -= 0xfee0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (std::size_t i{0}; i <= fc::lastHalfWidthItem; i++)
|
|
|
|
|
{
|
|
|
|
|
if ( fc::halfWidth_fullWidth[i][FULL] == c ) // found
|
|
|
|
|
c = fc::halfWidth_fullWidth[i][HALF];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
FString getColumnSubString ( const FString& str
|
|
|
|
|
, std::size_t col_pos, std::size_t col_len )
|
|
|
|
|
{
|
|
|
|
|
FString s(str);
|
|
|
|
|
std::size_t col_first{1}, col_num{0}, first{1}, num{0};
|
|
|
|
|
|
|
|
|
|
if ( col_len == 0 || s.isEmpty() )
|
|
|
|
|
return FString(L"");
|
|
|
|
|
|
|
|
|
|
if ( col_pos == 0 )
|
|
|
|
|
col_pos = 1;
|
|
|
|
|
|
|
|
|
|
for (auto&& ch : s)
|
|
|
|
|
{
|
|
|
|
|
std::size_t width = getColumnWidth(ch);
|
|
|
|
|
|
|
|
|
|
if ( col_first < col_pos )
|
|
|
|
|
{
|
|
|
|
|
if ( col_first + width <= col_pos )
|
|
|
|
|
{
|
|
|
|
|
col_first += width;
|
|
|
|
|
first++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ch = fc::SingleLeftAngleQuotationMark; // ‹
|
|
|
|
|
num = col_num = 1;
|
|
|
|
|
col_pos = col_first;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ( col_num + width <= col_len )
|
|
|
|
|
{
|
|
|
|
|
col_num += width;
|
|
|
|
|
num++;
|
|
|
|
|
}
|
|
|
|
|
else if ( col_num < col_len )
|
|
|
|
|
{
|
|
|
|
|
ch = fc::SingleRightAngleQuotationMark; // ›
|
|
|
|
|
num++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( col_first < col_pos ) // String length < col_pos
|
|
|
|
|
return FString(L"");
|
|
|
|
|
|
|
|
|
|
return s.mid(first, num);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::size_t getLengthFromColumnWidth ( const FString& str
|
|
|
|
|
, std::size_t col_len )
|
|
|
|
|
{
|
|
|
|
|
std::size_t column_width{0}, length{0};
|
|
|
|
|
|
|
|
|
|
for (auto&& ch : str)
|
|
|
|
|
{
|
|
|
|
|
if ( column_width < col_len )
|
|
|
|
|
{
|
|
|
|
|
column_width += getColumnWidth(ch);
|
|
|
|
|
length++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::size_t getColumnWidth (const FString& s, std::size_t pos)
|
|
|
|
|
{
|
|
|
|
|
if ( s.isEmpty() )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
std::size_t column_width{0};
|
|
|
|
|
auto length = s.getLength();
|
|
|
|
|
|
|
|
|
|
if ( pos > length )
|
|
|
|
|
pos = length;
|
|
|
|
|
|
|
|
|
|
for (std::size_t i{0}; i < pos; i++)
|
|
|
|
|
column_width += getColumnWidth(s[i]);
|
|
|
|
|
|
|
|
|
|
return column_width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::size_t getColumnWidth (const FString& s)
|
|
|
|
|
{
|
2019-10-14 01:44:24 +02:00
|
|
|
|
int column_width{0};
|
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
|
if ( s.isEmpty() )
|
|
|
|
|
return 0;
|
|
|
|
|
|
2019-10-14 01:44:24 +02:00
|
|
|
|
for (const auto& wchar : s)
|
|
|
|
|
column_width += getColumnWidth(wchar);
|
|
|
|
|
|
2019-10-08 04:37:19 +02:00
|
|
|
|
return ( column_width == -1 ) ? 0 : std::size_t(column_width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::size_t getColumnWidth (const wchar_t wchar)
|
|
|
|
|
{
|
|
|
|
|
int column_width{};
|
|
|
|
|
|
2019-10-14 01:44:24 +02:00
|
|
|
|
#if defined(__NetBSD__) || defined(__OpenBSD__) \
|
|
|
|
|
|| defined(__FreeBSD__) || defined(__DragonFly__) \
|
|
|
|
|
|| defined(__sun) && defined(__SVR4)
|
|
|
|
|
if ( hasAmbiguousWidth(wchar) )
|
|
|
|
|
column_width = 1;
|
|
|
|
|
else
|
|
|
|
|
#endif
|
|
|
|
|
|
2020-01-03 01:33:18 +01:00
|
|
|
|
if ( (wchar >= fc::NF_rev_left_arrow2 && wchar <= fc::NF_check_mark)
|
|
|
|
|
|| ! hasFullWidthSupports() )
|
2019-10-08 04:37:19 +02:00
|
|
|
|
column_width = 1;
|
|
|
|
|
else
|
|
|
|
|
column_width = wcwidth(wchar);
|
|
|
|
|
|
|
|
|
|
return ( column_width == -1 ) ? 0 : std::size_t(column_width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::size_t getColumnWidth (FChar& term_char)
|
|
|
|
|
{
|
|
|
|
|
std::size_t char_width = getColumnWidth(term_char.ch);
|
|
|
|
|
|
|
|
|
|
if ( char_width == 2 && FTerm::getEncoding() != fc::UTF8 )
|
|
|
|
|
{
|
|
|
|
|
term_char.ch = '.';
|
|
|
|
|
term_char.attr.bit.char_width = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
term_char.attr.bit.char_width = char_width & 0x03;
|
|
|
|
|
|
|
|
|
|
return char_width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
std::size_t getColumnWidth (const FTermBuffer& termbuffer)
|
|
|
|
|
{
|
|
|
|
|
std::size_t column_width{0};
|
|
|
|
|
|
|
|
|
|
for (auto&& tc : termbuffer)
|
|
|
|
|
column_width += tc.attr.bit.char_width;
|
|
|
|
|
|
|
|
|
|
return column_width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace finalcut
|